##数据结构##输入某二叉树的前序遍历和中序遍历的结果,重建出该二叉树

二叉树是数据结构中比较重要的一部分,通过给定的二叉树可以进行前序中序和后序遍历,但是反过来,如果给定前序遍历和中序遍历,是否可以重建出一棵二叉树。答案是,可以。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
 //使用vector容器作为参数
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
//判断给定的前序以及中序是否为空 
if(pre.size()==0||vin.size()==0)
            return NULL;
        int* preStart = &pre[0];        //取前序的第一个元素地址,定义一个指针指向
        int* preEnd = &pre[pre.size()-1];//取前序的最后一个元素地址,定义一个指针指向
        int* vinStart = &vin[0];//取中序的第一个元素地址,定义一个指针指向
        int* vinEnd = &vin[vin.size()-1];//取中序最后一个元素地址,定义一个指针指向
        return ConstructTree(preStart,preEnd,vinStart,vinEnd);
    }
    TreeNode* ConstructTree(int* preStart,int* preEnd,int* vinStart,int* vinEnd)
    {
        int data = preStart[0];//取出前序的第一个数据
        TreeNode* root = new TreeNode(data);//以该数据作为该重建树的根节点,因为由前序遍历的特点可知,第一个数据就是根节点
        if(preStart==preEnd)
        {
            if(preStart == vinEnd&& preEnd==vinStart)
                return root;
        }
        
        int* rootInorder = vinStart;//定义一个指针,开始遍历中序数组,直到找到根节点再停止,这样就可以分出左子树和右子树
        while(rootInorder<=vinEnd && *rootInorder!=data)
            ++rootInorder;
        if(rootInorder==vinEnd && *rootInorder!=root->val)
            return NULL;             //如果在中序中没有找到根节点则返回空
        int leftlength = rootInorder-vinStart;
        int* leftpreOrderEnd = preStart+leftlength;//根据在中序中找到的左子树就可以找出前序中的左子树
        //再依次根据递归即可重建该二叉树
         if(leftlength>0)
        {
           root->left = ConstructTree(preStart+1,leftpreOrderEnd,vinStart,rootInorder-1);
        }
        if(leftlength<preEnd-preStart)
        {
           root->right = ConstructTree(leftpreOrderEnd+1,preEnd,rootInorder+1,vinEnd);
        }
        return root;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36474990/article/details/79835198
今日推荐