题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},请重建出二叉树并输出它的头结点。
解法思路:在二叉树的前序遍历中,第一个数字总是树的根结点的值。但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边。因此我们要扫描中序序列,才能找到根结点的值。
找到了根结点之后,根结点的左边就是树的左子树,右边就是树的右子树,再依次递归即可。
C语言源代码:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *lchild;
struct Node *rchild;
};
//根据前序遍历和中序遍历重建二叉树
struct Node *construct(int *preorder,int *endpreorder,int *inorder,int *endinorder)
{
int *r;
int leftlens;
int *leftpreend;
int rootvalue = preorder[0];
struct Node *root = (struct Node *)malloc(sizeof(struct Node));
root->data = rootvalue;
root->lchild = NULL;
root->rchild = NULL;
if(preorder == endpreorder && inorder == endinorder && *preorder == *inorder)
return root;
r = inorder;
while(*r != rootvalue && r <= endinorder)
r++;
leftlens = r - inorder;
leftpreend = preorder+leftlens;
if(leftlens > 0)
root->lchild = construct(preorder+1,leftpreend,inorder,r-1);
if(leftlens < endpreorder-preorder)
root->rchild = construct(leftpreend+1,endpreorder,r+1,endinorder);
return root;
}
//后序打印二叉树
void houxu(struct Node *root)
{
if(root == NULL)
return;
houxu(root->lchild);
houxu(root->rchild);
printf(" %d ",root->data);
}
int main()
{
int lens;
int preorder[10];
int inorder[10];
int i;
struct Node *root;
printf("请输入序列元素个数:\n");
scanf("%d",&lens);
printf("请输入前序序列");
for(i=0;i<lens;i++)
scanf("%d",&preorder[i]);
printf("请输入中序序列");
for(i=0;i<lens;i++)
scanf("%d",&inorder[i]);
root = construct(preorder,preorder+lens-1,inorder,inorder+lens-1);
houxu(root);
return 0;
}
转载于:https://blog.51cto.com/7876369/1557464