您的位置:首页 > 其它

根据二叉树的前序遍历和中序遍历结果重建二叉树

2013-12-13 20:13 453 查看
根据二叉树的前序遍历和中序遍历的结果重建二叉树,假设输入的前序遍历和中序遍历的结果中都不包含重复的数字。

以下为实例程序:

#include <stdio.h>
#include <stdlib.h>

typedef struct BinaryTreeNode
{
int m_nValue;
struct BinaryTreeNode* m_pLeft;
struct BinaryTreeNode* m_pRight;
}BinaryTreeNode;

BinaryTreeNode* ConstructCore(int *startPreorder,int* endPreorder,int* startInorder,int* endInorder);

//构建二叉树
BinaryTreeNode*
Construct(int *preorder,int *inorder,int length)
{
if(preorder==NULL || inorder==NULL || length<=0)
{
printf("输入错误!\n");
return NULL;
}
else
{
return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}
}

//构建结点
BinaryTreeNode*
ConstructCore(int *startPreorder,int *endPreorder,int* startInorder,int* endInorder)
{
//前序遍历的第一个数字是根结点的值
int rootValue=*startPreorder;
BinaryTreeNode *root=(BinaryTreeNode *)malloc(sizeof(BinaryTreeNode));
root->m_nValue=rootValue;
root->m_pLeft=root->m_pRight=NULL;

//只有一个结点
if(startPreorder==endPreorder)
{
if(startInorder==endInorder&&  *startPreorder==*startInorder)
return root;
else
{
printf("输入错误!\n");
exit(0);
}
}

int *rootInorder=startInorder;
while(rootInorder<=endInorder && *rootInorder!=rootValue)
{
rootInorder++;
}
if(rootInorder==endInorder && *rootInorder!=rootValue)
{
printf("输入错误!\n");
exit(0);
}

//在中序遍历中找到根结点的值
int leftLength=rootInorder-startInorder;
int *leftPreorderEnd=startPreorder+leftLength;
if(leftLength>0)
{
//左子树递归
root->m_pLeft=ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
}
if(leftLength<endPreorder-startPreorder)
{
//右子树递归
root->m_pRight=ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}

//后序遍历
void LastOrder(BinaryTreeNode *root,int* lasorder,int* index)
{
if(root!=NULL)
{
if(root->m_pLeft!=NULL){
LastOrder(root->m_pLeft,lasorder,index);
}
if(root->m_pRight!=NULL){
LastOrder(root->m_pRight,lasorder,index);
}
lasorder[*index]=root->m_nValue;
*index=*index+1;
}
}

int
main(void)
{
int *preorder;
int *inorder;
int *lasorder;
int length;
int i;
BinaryTreeNode* tree=NULL;
int index=0;

printf("输入结点数:\n");
scanf("%d",&length);
preorder=(int *)malloc(length*sizeof(int));
inorder=(int *)malloc(length*sizeof(int));
lasorder=(int *)malloc(length*sizeof(int));
printf("输入前序遍历序列:");
for(i=0;i<length;i++)
{
scanf("%d",&preorder[i]);
}
printf("输入中序遍历序列:");
for(i=0;i<length;i++)
{
scanf("%d",&inorder[i]);
}
tree=Construct(preorder,inorder,length);
if(tree!=NULL)
{
printf("构造二叉树成功!\n");

}
else{
printf("构造二叉树失败!\n");
return 0;
}
LastOrder(tree,lasorder,&index);
for(i=0;i<length;i++)
{
printf("%d ",lasorder[i]);
}
printf("\n");
return 0;
}


前序遍历的第一个值为根结点的值。在中序遍历中找到根结点,左边为左子树,右边为右子树。

运行结果:

不完全二叉树:



完全二叉树:



只有一个结点:



只有右子树:



只有左子树:



前序遍历与中序遍历不匹配:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐