首页 > 代码库 > 重建二叉树

重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。输入前序遍历序列{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;
}


重建二叉树