重建二叉树

来源:互联网 发布:创维32e500e数据 编辑:程序博客网 时间:2024/06/13 23:29

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

说起来一直以来并不是不会由前序遍历、中序遍历推出二叉树,但是一直以来都是死推,并没有从中找什么规律。今天看到这个题了,才发现其中的规律。前序的一个节点一定是根节点,然后从中序序列中找这个根节点,这个节点左边的节点一定是根的左子树的节点,右边的节点一定是根的右子树上的节点。而且这个序列正好又是左子树的中序序列,计算这个序列的个数n,从前序序列中去掉第一个点,往后数n个节点,便是根的左子树的前序序列,结合左子树的前序遍历和中序遍历又可以往下推。递归下去便可得到整个二叉树。结合上边的例子来看就是从前序序列可以知道1是根节点,从中序序列中找到节点1,1的左边便是根的左子树的中序序列vin1{4,7,2},1的右边便是根的右子树的中序序列vin2{5,3,8,6};这时候可以数出1的左边有3个节点,从前序序列中除第一个节点外数出3个节点{2,4,7},那么这3个节点组成的序列就是根的左子树的前序序列pre1{2,4,7},剩下的节点组成的序列为根的右子树的前序序列pre2{3,5,6,8}。得到左右子树的前序序列和中序序列后重复的进行这个过程就好了。

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public:    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {        if(pre.size() == 0)            return NULL;        TreeNode *pnode, *noderight, *nodeleft;        vector<int> pre1;        vector<int> vin1;        vector<int> pre2;        vector<int> vin2;        pnode = (TreeNode *)malloc( sizeof(TreeNode));        int len = pre.size(), i = 0, j = 0;        int tmp = pre.at(0);        pnode->val = tmp;        pnode->right = NULL;        pnode->left = NULL;        for(i = 0; i < len; i++){            if(vin[i] == tmp)                break;            else                vin1.push_back(vin[i]) ;        }        for(j = 1; j < i + 1; j++)            pre1.push_back(pre[j]);        for(i = i + 1; i < len; i++)            vin2.push_back(vin[i]);        for(; j < len; j++)            pre2.push_back(pre[j]);        nodeleft = reConstructBinaryTree(pre1,vin1);        noderight = reConstructBinaryTree(pre2,vin2);        pnode->left = nodeleft;        pnode->right = noderight;        return pnode;    }};
原创粉丝点击