您的位置:首页 > 其它

利用中根序列和后根序列重建二叉树

2015-03-22 20:10 260 查看
问题:已知二叉树的后根序列和中根序列,请构造此二叉树。

分析:对于提供了后根序列和中根序列的一棵二叉树,其结构信息是完备的。考虑后根序列a(1)->a(n),中根序列b(1)->b(n)。我们知道中根序列b(1)->b(n)包含一颗完整的二叉树,那么中根序列里面肯定有一个元素b(i)是该二叉树的根。而根据中根序列的定义,b(i)前面的元素构成的一个序列b(1)->b(i-1)是该二叉树左子树的中根序列,b(i)后面的元素构成的序列b(i+1)->b(n)是该二叉树的右子树的中根序列。则由b(x)->b(y)产生一棵二叉树的过程可以递归的表述为:

1.找到b(x)->b(y)中的某个元素b(i)作为该树的根

2.由b(x)->b(i-1)产生一棵二叉树作为该树的左子树

3.由b(i+1)->b(y)产生一棵二叉树作为该树的右子树

现在问题归结到寻找根节点b(i),这时候就需要用到后根序列a(1)->a(n),由后根序列的定义可知,对任何一颗树(包括后根序列本身表达的那棵树和该树的所有子树),其根节点一定出现在它包含的其他节点之后,那么只要找到b(x)->b(y)中最后在后根序列里出现的元素,就是我们要的b(i),具体步骤如下:

1.设置循环,从a(1)->a(n)依次取出a(j)

2.对每一个a(j),找到它在b(1)->b(n)中对应的序号j',即b(j')=a(j)

3.若x<j'<y,则跳出循环,b(j')即为b(i)

实例(百练—2015研究生上机测试)

描述:输入一棵二叉树的中根序列和后根序列,要求在内存中重建二叉树,最后输出这颗二叉树的先根序列。

用不同的整数来唯一标识二叉树的每一个结点,下面的二叉树

5

/ \

9 67

/

32

中根:9 5 32 67

后根:9 32 67 5

先根:5 9 67 32

输入:两行,第一行是二叉树的中根序列,第二行是后根序列。每个数字表示的结点之间用空格分隔。结点数字范围0~65535。

输出:二叉树的先根序列。每个数字表示的结点之间用空格分隔。

样例输入:

9 5 32 67

9 32 67 5

样例输出:

5 9 67 32
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

vector<int> BinTree;    //存储输入的中根序列和后根序列
int Btree[65536];       //二叉树的顺序存储

void travel(int x,int y,int r,int index){
Btree[index]=BinTree[r];                //顺序存储重建的二叉树
if(x==y)
return;

int j,left,right;
for(j=x;j<=y;j++)
if(BinTree[j]==BinTree[r])          //寻找根节点
break;

if(x<j){
left=r-y+j-1;                       //左子树根节点
printf(" %d",BinTree[left]);        //输出二叉树的先根序列
travel(x,j-1,left,index<<1);        //构造左子树
}
if(j<y){
right=r-1;                          //右子树根节点
printf(" %d",BinTree[right]);       //输出二叉树的先根序列
travel(j+1,y,right,(index<<1)+1);   //构造右子树
}
}

int main(){
freopen("in.txt","r",stdin);    //调试

int a,n=0;
while(scanf("%d",&a)!=EOF){
BinTree.push_back(a);
n++;
}

memset(Btree,-1,sizeof(Btree)); //顺序存储数组的初始化
printf("%d",BinTree[n-1]);      //输出二叉树的先根序列
travel(0,(n>>1)-1,n-1,1);

fclose(stdin);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: