算法题17 重建二叉树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法题17 重建二叉树相关的知识,希望对你有一定的参考价值。

题目

  已知一个二叉树的前序和中序遍历数组,构建这个二叉树。如已知前序为:abcdf,中序为:cbdaf,可以构建出这个二叉树为 a

                                                        /  \

                                                        b  f

                                                       /  \

                                                       c  d

分析

  已知前序和中序排列或者已知后序和中序排列,思路都是通过前序或者后序确定树或子树的根节点,通过中序找到根节点所在的位置;

  中序的根节点左边的是左子树的元素(也是中序),右边是右子树的元素;确定好左右子树元素序列长度后依次递归构建左子树和右子树。

代码

 1 //已知前序和中序排列,构建二叉树
 2 TreeNode* ConstructCore(char* start_porder,char* end_porder,char* start_morder,char* end_morder)
 3 {
 4     TreeNode* node=new TreeNode();
 5     node->value=*start_porder;
 6     node->pLeft=NULL;
 7     node->pRight=NULL;
 8 
 9     if (start_morder==end_morder)
10     {
11         return node;
12     }
13 
14     //find the position of the first value of preorder array in the middle order array. 
15     char* p=start_morder;
16     while(start_morder<=end_morder&&*p!=node->value)
17     {
18         p++;
19     }
20 
21     if (p==end_morder&&*p!=node->value)
22         throw std::exception("Invalid input.");
23 
24     int left_len=p-start_morder;
25 
26     if (left_len>0)
27     {
28         node->pLeft=ConstructCore(start_porder+1,start_porder+left_len,start_morder,p-1);
29     }
30     if ((end_porder-start_porder)>left_len)
31     {
32         node->pRight=ConstructCore(start_porder+left_len+1,end_porder,p+1,end_morder);
33     }
34 
35     return node;
36 
37 }
38 
39 TreeNode* ConstructTree(char* arry_porder,char* arry_morder,int len)
40 {
41     TreeNode* root=new TreeNode();
42     
43     return ConstructCore(arry_porder,arry_porder+len-1,arry_morder,arry_morder+len-1);
44 }

 

 1 //已知后序和中序排列,构建二叉树
 2 TreeNode* ConstructCore2(char* start_post,char* end_post,char* start_morder,char* end_morder)
 3 {
 4     TreeNode* node=new TreeNode();
 5     node->value=*end_post;
 6     node->pLeft=NULL;
 7     node->pRight=NULL;
 8 
 9     if (start_morder==end_morder)
10     {
11         return node;
12     }
13 
14     //find the position of the last value of post order array in the middle order array. 
15     char* p=start_morder;
16     while(start_morder<=end_morder&&*p!=node->value)
17     {
18         p++;
19     }
20 
21     if (p==end_morder&&*p!=node->value)
22         throw std::exception("Invalid input.");
23 
24     int left_len=p-start_morder;
25 
26     if (left_len>0)
27     {
28         node->pLeft=ConstructCore(start_post,start_post+left_len-1,start_morder,p-1);
29     }
30     if ((end_post-start_post)>left_len)
31     {
32         node->pRight=ConstructCore(start_post+left_len,end_post-1,p+1,end_morder);
33     }
34 
35     return node;
36 
37 }
38 
39 TreeNode* ConstructTree(char* arry_porder,char* arry_morder,int len)
40 {
41     TreeNode* root=new TreeNode();
42     
43     return ConstructCore2(arry_porder,arry_porder+len-1,arry_morder,arry_morder+len-1);
44 }

  

对于什么已知前序和后序不能确定唯一的一个二叉树,可以通过举例证明:如二叉树  a   和  a      的前序遍历都是abc,后序遍历都是cba。由此我们可以知道,如果二叉树中有一个子树结构是这种非满的结构,将不能确定子叶节点在左边还是在右边

                                      /        \

                                      b        b

                                     /          \

                                     c          c

以上是关于算法题17 重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章

每日一道算法题04:重建二叉树

[编程题]重建二叉树

剑指Offer面试题:07 重建二叉树

剑指Offer面试题:09 重建二叉树

剑指offer重建二叉树

面试题:重建二叉树