对于一颗二叉树,可以根据先序遍历(后序遍历)和中序遍历重新还原出二叉树。
主要通过递归实现。
关键是找出对应左右子树的长度,之后传递先序遍历的开始节点、结束节点,中序遍历的开始节点、结束节点。
代码:
#include <iostream>
using namespace std;
typedef struct tree{
int data;
struct tree *lchild;
struct tree *rchild;
}Tree, *pTree;
pTree reConstruct(int *startPre,int *endPre,int *startIn,int *endIn){
pTree root = new Tree();
root->data = startPre[0];
root->lchild = NULL;
root->rchild = NULL;
//找到根节点
int rootValue = startPre[0];
// 递归返回
if(startPre == endPre){
if(endIn == startIn && *startPre == *startIn){
return root;
}else
throw exception("invalid input");
}
//下面是找长度,确定下次递归指针,即中序遍历中根节点的位置
int *rootIn = startIn;
while(rootIn < endIn && *rootIn != rootValue){
rootIn++;
}
if(rootIn == endIn && *rootIn != rootValue)
throw exception("invalid input");
int leftLength = rootIn - startIn;
//构建左子树
if(leftLength > 0){
root->lchild = reConstruct(startPre + 1,startPre + leftLength ,startIn,startIn + leftLength-1);
}
//构建右子树
if((endIn - rootIn) >0){
root->rchild = reConstruct(startPre + leftLength +1,endPre,startIn + leftLength+1,endIn);
}
return root;
}
pTree construct(int *preOrder,int *inOrder,int length){
if(preOrder == NULL || NULL == inOrder || length < 0)
return NULL;
return reConstruct(preOrder,preOrder + length - 1,inOrder,inOrder + length - 1);
}
void print(const pTree pHead){
if(pHead){
cout<< pHead ->data <<" ";
print(pHead ->lchild);
print(pHead ->rchild);
}
}
int main()
{
pTree pHead = NULL;
int preOrder[] = {1,2,4,7,3,5,6,8};
int inOrder[] = {4,7,2,1,5,3,8,6};
pHead = construct(preOrder,inOrder,sizeof(preOrder) / sizeof(int));
print(pHead);
return 0;
}
运行结果:
和先序遍历输入一样: