18.二叉树遍历序列还原

1 问题

给出二叉树的中序遍历序列和后序遍历序列,编程还原该二叉树。

输入:
  第1行为二叉树的中序遍历序列
  第2行为二叉树的后序遍历序列

输出:
  二叉树的按层遍历序列

 测试输入 期待的输出 时间限制 内存限制 额外进程
测试用例 1以文本方式显示
  1. badcfeg↵
  2. bdfgeca↵
以文本方式显示
  1. abcdefg↵
1秒64M0
测试用例 2以文本方式显示
  1. cbdafeg↵
  2. cbdfgea↵
以文本方式显示
  1. adebfgc↵
1秒64M0
测试用例 3以文本方式显示
  1. edcba↵
  2. edcba↵
以文本方式显示
  1. abcde↵
1秒64M0

2 解题

思想:递归+队列

  • 还原二叉树的基本原理
    在这里插入图片描述

这里得到的新的字符串来创立子树的时候和刚开始一模一样,使用递归重复操作即可完成,给定出递归的条件就好

  • 层序遍历,相当于BFS(广度优先算法),借助队列来实现
  • 基本原理
    在这里插入图片描述
  1. 把根节点A放入队列,此时队列为:A,队列头指针指向A,也就是队列第一个元素

  2. 把当前队列头指针所指元素的左右儿子放入队列,即将B C放入队列,此时队列为A B C ,队列头指针向下移一格,此时指向B

  3. 不断重复2步骤。此时把B的左右儿子取出来放入队尾,队列变为A B C D E,队列头指针后移,指向c,c没有子节点,队列不再延长;

  4. 结束条件,队列头指针和为指针重合时,输出最后一个元素,算法结束!
    也就是说,把这个队列从头到尾输出一遍,就是按层遍历,这个队列是动态的,只要有子节点,子节点就会不停的加入队尾,但总有子节点没有的时候,所以,队列尾指针肯定有不再移动的时候,而头指针一直在一步一步向下移,总会有首尾指针重合的时候,即标志着算法结束。

  • 如果使用递归的话就直接走到底了,成了DFS(深度优先算法)
  • 这里可以自己写一个栈,但是为了省事我直接用了c++模板库里面的队列queue
  • 基本用法
  1. 定义一个queue的变量 queue M
  2. 查看是否为空范例 M.empty() 是的话返回1,不是返回0;
  3. 从已有元素后面增加元素 M.push()
  4. 输出现有元素的个数 M.size()
  5. 显示第一个元素 M.front()
  6. 显示最后一个元素 M.back()
  7. 清除第一个元素 M.pop()
  8. 头文件 include<queue>
  9. 声明队列变量 queue<Type> variable_name

  • 代码如下
#include <cstdio>
#include <cstdlib>
#include <iomanip>  //cout函数格式化输出头文件
#include <iostream>
#include<cstring>
#include<queue>

using namespace std;

typedef struct BiNode {
    char element;
    struct BiNode *left;
    struct BiNode *right;
} * BiTree;

//使用返回值建立二叉树 
BiTree BiTreeCreat(char str1[],char str2[],BiTree rt){      //函数代码的大部分都是在复制字符串
    int len = strlen(str1);

    if(len==0)
        rt=NULL;
    else if(len==1){
        char p = str2[len-1];
        rt = (BiTree)malloc(sizeof(struct BiNode));
        rt->element = p;
        rt->left=NULL;
        rt->right=NULL;
    }
    else{
        char p = str2[len-1];
        rt = (BiTree)malloc(sizeof(struct BiNode));
        rt->element = p;
        rt->left=NULL;
        rt->right=NULL;
        char s1[len+1],s2[len+1];
        int i,j=0;
        for(i=0;i<len;i++){
            if(str1[i]==p)
                break;
            s1[i]=str1[i];
        }
        s1[i]='\0';
        for(j=0;j<i;j++){
            s2[j]=str2[j];
        }
        s2[j]='\0';
        rt->left = BiTreeCreat(s1,s2,rt->left);
        if(str1[i]==p)
            i++;        
        int m,n;
        for(m=0;i<len;i++){
            s1[m++]=str1[i];
        }
        s1[m]='\0';
        for(n=0;n<m;n++){
            s2[n]=str2[n+j];
        }
        s2[n]='\0';
        rt->right = BiTreeCreat(s1,s2,rt->right);
    }

    return rt;
}

void treelevelorder(BiTree rt){
    queue<BiTree> q;   
    if(!rt) 
        return ;
    q.push(rt); //入队,开始操作
    while(!q.empty()){
        rt = q.front();        
        q.pop();
        cout<<rt->element;
        if(rt->left)
            q.push(rt->left);
        if(rt->right)
            q.push(rt->right);
        
    }
    cout<<endl;
}

int main() {
    //freopen("file in.txt", "r", stdin);
    BiTree root;
    root = NULL;
    char str1[40];
    char str2[40];
    char ch;
    int i=0;
    ch = getchar();
    while(ch!='\n'){        
        str1[i++] =ch;
        ch=getchar();
    }
    str1[i]='\0';
    i=0;
    // 上一行的回车已经被读取了
    ch = getchar();
    while(ch!='\n'){        
        str2[i++] = ch;
        ch=getchar();
    }
    str2[i]='\0';
    // 使用返回值创建二叉树,如果不用返回值的话需要用二级指针
    root = BiTreeCreat(str1,str2,root);

    treelevelorder(root);
    return 0;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值