算法题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 重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章