题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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、分析复杂问题时千万不要怕麻烦,以后遇到的问题肯定都不是一眼就能看出结果的,如果有思路,不要怕麻烦而不去实现它,切记!