您的位置:首页 > 其它

算法题17 重建二叉树

2016-03-14 16:37 267 查看
题目
  已知一个二叉树的前序和中序遍历数组,构建这个二叉树。如已知前序为: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: