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