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

来源:互联网 发布:java编程工具安卓 编辑:程序博客网 时间:2024/06/06 15:41
问题:已知二叉树的后根序列和中根序列,请构造此二叉树。

 分析:对于提供了后根序列和中根序列的一棵二叉树,其结构信息是完备的。考虑后根序列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;}

0 0
原创粉丝点击