1 问题
给出二叉树的中序遍历序列和后序遍历序列,编程还原该二叉树。
输入:
第1行为二叉树的中序遍历序列
第2行为二叉树的后序遍历序列
输出:
二叉树的按层遍历序列
2 解题
思想:递归+队列
- 还原二叉树的基本原理
这里得到的新的字符串来创立子树的时候和刚开始一模一样,使用递归重复操作即可完成,给定出递归的条件就好
- 层序遍历,相当于BFS(广度优先算法),借助队列来实现
- 基本原理
-
把根节点A放入队列,此时队列为:A,队列头指针指向A,也就是队列第一个元素
-
把当前队列头指针所指元素的左右儿子放入队列,即将B C放入队列,此时队列为A B C ,队列头指针向下移一格,此时指向B
-
不断重复2步骤。此时把B的左右儿子取出来放入队尾,队列变为A B C D E,队列头指针后移,指向c,c没有子节点,队列不再延长;
-
结束条件,队列头指针和为指针重合时,输出最后一个元素,算法结束!
也就是说,把这个队列从头到尾输出一遍,就是按层遍历,这个队列是动态的,只要有子节点,子节点就会不停的加入队尾,但总有子节点没有的时候,所以,队列尾指针肯定有不再移动的时候,而头指针一直在一步一步向下移,总会有首尾指针重合的时候,即标志着算法结束。
- 如果使用递归的话就直接走到底了,成了DFS(深度优先算法)
- 这里可以自己写一个栈,但是为了省事我直接用了c++模板库里面的队列queue
- 基本用法
- 定义一个queue的变量 queue M
- 查看是否为空范例 M.empty() 是的话返回1,不是返回0;
- 从已有元素后面增加元素 M.push()
- 输出现有元素的个数 M.size()
- 显示第一个元素 M.front()
- 显示最后一个元素 M.back()
- 清除第一个元素 M.pop()
- 头文件 include<queue>
- 声明队列变量 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;
}