重建二叉树

来源:互联网 发布:手机如何共享wifi网络 编辑:程序博客网 时间:2024/06/05 07:49

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果都不含重复的 数字。例如,输入前序遍历{ 1, 2, 4, 7, 3, 5, 6, 8 },后序遍历{ 4, 7, 2, 1, 5, 3, 8, 6 },重建二叉树。

思路:

我们可以利用递归思想。利用前序遍历我们不难发现前序遍历的首元素就是树的根节点。而中序遍历是先访问左子树,根,右子树。我们就可以在中序遍历中找到节点。根节点左边的元素就左子树,右边的元素就是右子树。然后利用递归继续构建左子树,右子树,最后重建二叉树。

代码实现:

#include<iostream>#include<assert.h>using namespace std;typedef struct TreeNode{int _value;TreeNode* _left;TreeNode* _right;TreeNode(const int value):_value(value), _left(NULL), _right(NULL){}}Node;Node* ConstructTree(int* startPrevOrder, int* endPrevOrder, int* startInOrder, int* endInOrder){//根节点->前序遍历的第一个元素Node* root = new Node(*startPrevOrder);//叶子节点if (startPrevOrder == endPrevOrder)//前序遍历只有一个节点{if (startInOrder == endInOrder && *startPrevOrder == *endPrevOrder){   //中序遍历只有一个节点return root;}else{assert(false);}}//在中序遍历找根节点int* rootInOrder = startInOrder;while (rootInOrder <= endInOrder && *rootInOrder != *startPrevOrder){++rootInOrder;}if (rootInOrder == endInOrder && *rootInOrder != *startPrevOrder){//参数有误;assert(false);}//成功找到根节点int leftLength = rootInOrder - startInOrder;int* leftPrevOrderEnd = startPrevOrder + leftLength; //左子树的尾//中序遍历的根的 左边是左子树,右边是右子树if (leftLength > 0){//构建左子树root->_left = ConstructTree(startPrevOrder + 1, leftPrevOrderEnd, startInOrder, rootInOrder - 1);}if (leftLength < endPrevOrder - startPrevOrder){root->_right = ConstructTree(leftPrevOrderEnd + 1, endPrevOrder, rootInOrder + 1, endInOrder);}return root;}//构建二叉树Node* Construct(int* prevOrder, int* inOrder, size_t n){assert(prevOrder);assert(inOrder);assert(n);return ConstructTree(prevOrder, prevOrder + n - 1, inOrder, inOrder + n - 1);}void Test(){int preOrder[] = { 1, 2, 4, 7, 3, 5, 6, 8 };   //正常的树int inOrder[] = { 4, 7, 2, 1, 5, 3, 8, 6 };//int preOrder[] = { 1};//一颗节点的树//int inOrder[] = { 4};Node *root = Construct(preOrder, inOrder, sizeof(preOrder) / sizeof(*preOrder));}int main(){Test();system("pause");return 0;}


0 0