码迷,mamicode.com
首页 > 其他好文 > 详细

【剑指offer】重建二叉树

时间:2014-07-02 08:58:17      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:二叉树   重构二叉树   

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。二叉树结点的定义如下:

struct TreeNode{
         ElemType data;
         TreeNode*left;
         TreeNode*right;
};

分析:前序遍历的第一个数1就是根结点,中序遍历中1之前的数组成了左子树,也就是4,7,2是左子树,1之后的数组成了右子树,也就是3,8,6是右子树。对于前序遍历的2,4,7同样仍然是前序遍历,因此,重建整个数就可以分解成重建左子树和重建右子树。左子树的前序遍历是2,4,7,中序遍历是4,7,2。依次类推……因此我们可以用递归的方法解决此问题。

程序示例:

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

typedef int ElemType;
typedef struct TreeNode{
	ElemType	data;
    struct TreeNode	*left;
	struct TreeNode	*right;
}TreeNode, *pTreeNode;

pTreeNode ConstructCore
(int *startPreorder, int *endPreorder,
 int *startInorder, int *endInorder)
{
	int rootValue = startPreorder[0];
	pTreeNode BTree = (struct TreeNode *)malloc(sizeof(TreeNode));
	BTree->data = rootValue;
	BTree->left = BTree->right = NULL;

	if(startPreorder == endPreorder){
		if(startInorder == endInorder && *startPreorder == *startInorder)	
			return BTree;
		else
			puts("Invalid input.\n");
	}

	int *rootInorder = startInorder;
	while(rootInorder <= endInorder && *rootInorder != rootValue)
		++rootInorder;
	if(rootInorder == endInorder && *rootInorder != rootValue)
		puts("Invalid input.\n");

	int leftLength = rootInorder - startInorder;
	int *leftPreorderEnd = startPreorder + leftLength;
	if(leftLength > 0){
		BTree->left = ConstructCore(startPreorder + 1,
						leftPreorderEnd, startInorder, rootInorder -1);	
	}
	if(leftLength < endPreorder - startPreorder){
		BTree->right = ConstructCore(leftPreorderEnd +1,
						endPreorder, rootInorder + 1, endInorder);	
	}

	return BTree;

}

pTreeNode RebuildTree(int *preorder, int *inorder, int length)
{
	pTreeNode BTree;
	
	if(preorder == NULL || inorder == NULL || length <= 0)
		return NULL;

	return ConstructCore(preorder, preorder+length-1, inorder, inorder+length-1);
}

int
main(int argc, char **argv)
{
	int n, i = 0;
	int tmp;
	printf("please input the number of the tree:");
	scanf("%d",&n);
	int prearray[n];
	int inarray[n];
	printf("please input the preorder of the tree:");
	do{
		scanf("%d",&tmp);
		prearray[i] = tmp;
		i++;
	}while(i < n);

	i = 0;
	printf("please input the inorder of the tree:");
	do{
		scanf("%d", &tmp);	
		inarray[i] = tmp;
		i++;
	}while(i < n);

	printf("the preorder is :\n");
	for(i = 0; i < n; i++){
		printf("%d\t",prearray[i]);
	}	
	putchar('\n');
	printf("the inorder is :\n");
	for(i = 0; i < n; i++){
		printf("%d\t",inarray[i]);
	}
	putchar('\n');

    RebuildTree(prearray, inarray, n);
	
	return 0;
}

总结:

1、对于树的三种遍历,要牢牢的掌握。

2、分析复杂问题时千万不要怕麻烦,以后遇到的问题肯定都不是一眼就能看出结果的,如果有思路,不要怕麻烦而不去实现它,切记!


【剑指offer】重建二叉树,布布扣,bubuko.com

【剑指offer】重建二叉树

标签:二叉树   重构二叉树   

原文地址:http://blog.csdn.net/to_be_it_1/article/details/36176649

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!