由前序遍歷和中序遍歷重新構建二叉樹

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。

思路:熟悉怎麼根據前序和中序遍歷確定一棵二叉樹的方法後,怎麼編碼是關鍵。關於二叉樹的大多數問題都是可以用遞歸的思路完成分別設置前序遍歷的兩個範圍索引prestart,preend和中序遍歷的兩個索引midstart,midend。每次從中序遍歷中尋找與pre[prestart]相等的mid[i],例如從前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}前序中的pre[prestart](1)和中序中的mid[3],以此劃分爲兩部分。

剩下的遞歸調用就是邊界的傳值問題。

                cur->left=_reConstructBinaryTree(pre,prestart+1,prestart+(i-midstart),mid,midstart,i-1);//前序的索引從前序中prestart的下一位到prestart+(i-midstart)這一位。下面同理,把數據帶入很容易看懂。
                cur->right=_reConstructBinaryTree(pre,prestart+(i-midstart)+1,preend,mid,i+1,midend);//右子樹要跨過左子樹,從左子樹的右邊索引加1爲起始位置。

完整代碼:

/**
 * 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()!=vin.size()||pre.size()==0)
            return NULL;
        TreeNode* root=_reConstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1);
        return root;

    }
private:
    //前序遍歷{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}
    TreeNode* _reConstructBinaryTree(vector<int> pre,int prestart,int preend,vector<int> mid,int midstart,int midend){
        if(prestart>preend||midstart>midend)//判斷沒有左子樹或者沒有右子樹
            return NULL;
        TreeNode* cur=new TreeNode(pre[prestart]);
        for(int i=midstart;i<=midend;i++){
            if(pre[prestart]==mid[i]){
                cur->left=_reConstructBinaryTree(pre,prestart+1,prestart+(i-midstart),mid,midstart,i-1);
                cur->right=_reConstructBinaryTree(pre,prestart+(i-midstart)+1,preend,mid,i+1,midend);
            }
        }
        return cur;
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章