题目:给定前序和终须遍历的结果,重建出二叉树。
//面试题6,重建二叉树
#include <iostream>
using namespace std;
typedef struct btree
{
int value;
btree *lchild;
btree *rchild;
}btree;
//销毁树,释放内存
void DestroyTree(btree* T)
{
if(T!=NULL)
{
DestroyTree(T->lchild);
DestroyTree(T->rchild);
delete T;
}
}
//后序遍历输出
void postOrder(btree *bt)
{
if(bt == NULL)
return;
if(bt->lchild != NULL)
postOrder(bt->lchild);
if(bt->rchild != NULL)
postOrder(bt->rchild);
printf("%d ",bt->value);
}
//重建树
btree *ConstructBtree(int *preorder,int *inorder, int length)
{
if(preorder == NULL || inorder == NULL || length <= 0)
return NULL;
//重建根节点
int rootvalue = *preorder;
btree *root = new btree();
root->value = rootvalue;
root->lchild = root->rchild = NULL;
//递归结束条件,前序和后序都剩下一个节点
if(length == 1)
{
if(*preorder == *inorder)
return root;
else
{
cout<<"Invalid input"<<endl;
return NULL;
}
}
//找到中序遍历中根节点位置
int rootid = 0;
while(rootid < length && *(inorder+rootid) != rootvalue)
rootid++;
//如果没找到中序遍历的根节点,证明输入的序列有误
if(*(inorder+rootid) != rootvalue)
{
cout<<"Invalid input"<<endl;
return NULL;
}
//左右子树的长度
int lchildlen = rootid;
int rchildlen = length - rootid - 1;
//若左、右子树有长度不为零的,就递归建造
if(lchildlen > 0)
root->lchild = ConstructBtree(preorder+1, inorder, lchildlen);
if(rchildlen > 0)
root->rchild = ConstructBtree(preorder+rootid+1, inorder+rootid+1,rchildlen);
return root;
}
//========================Test====================================
void Test(char* testName, int* preorder, int* inorder, int length)
{
if(testName != NULL)
printf("%s begins:\n", testName);
printf("The preorder sequence is: ");
for(int i = 0; i < length; ++ i)
printf("%d ", preorder[i]);
printf("\n");
printf("The inorder sequence is: ");
for(int i = 0; i < length; ++ i)
printf("%d ", inorder[i]);
printf("\n");
btree *root = ConstructBtree(preorder,inorder,length);
cout<<"The postorder is:"<<endl;
postOrder(root);
cout<<endl;
DestroyTree(root);
}
// 普通二叉树
// 1
// / \
// 2 3
// / / \
// 4 5 6
// \ /
// 7 8
void Test1()
{
const int length = 8;
int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};
int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};
Test("Test1", preorder, inorder, length);
}
// 所有结点都没有右子结点
// 1
// /
// 2
// /
// 3
// /
// 4
// /
// 5
void Test2()
{
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int inorder[length] = {5, 4, 3, 2, 1};
Test("Test2", preorder, inorder, length);
}
// 所有结点都没有左子结点
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
void Test3()
{
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int inorder[length] = {1, 2, 3, 4, 5};
Test("Test3", preorder, inorder, length);
}
// 树中只有一个结点
void Test4()
{
const int length = 1;
int preorder[length] = {1};
int inorder[length] = {1};
Test("Test4", preorder, inorder, length);
}
// 完全二叉树
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
void Test5()
{
const int length = 7;
int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
int inorder[length] = {4, 2, 5, 1, 6, 3, 7};
Test("Test5", preorder, inorder, length);
}
// 输入空指针
void Test6()
{
Test("Test6", NULL, NULL, 0);
}
// 输入的两个序列不匹配
void Test7()
{
const int length = 7;
int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
int inorder[length] = {4, 2, 8, 1, 6, 3, 7};
Test("Test7: for unmatched input", preorder, inorder, length);
}
int main( )
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
// const int length = 8;
// int preorder[length] = {1, 2, 4, 7, 3, 5, 6, 8};
// int inorder[length] = {4, 7, 2, 1, 5, 3, 8, 6};
//
// btree *root = ConstructBtree(preorder,inorder,length);
// postOrder(root);
// DestroyTree(root);
return 0;
}
运行结果: