如何通過二叉樹的前序和中序遍歷生成二叉樹

牛客網上的一道練習題:

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

以上就是我們的需求,關於樹的相關基礎知識請移步本人博客
js高級進階之數據結構“二叉排序樹”的es5和es6實現與應用

鏈接:https://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6?answerType=1&f=discussion
來源:牛客網

1. 分析

根據中序遍歷和前序遍歷可以確定二叉樹,具體過程爲:

根據前序序列第一個結點確定根結點
根據根結點在中序序列中的位置分割出左右兩個子序列
對左子樹和右子樹分別遞歸使用同樣的方法繼續分解
例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

根據當前前序序列的第一個結點確定根結點,爲 1
找到 1 在中序遍歷序列中的位置,爲 in[3]
切割左右子樹,則 in[3] 前面的爲左子樹, in[3] 後面的爲右子樹
則切割後的左子樹前序序列爲:{2,4,7},切割後的左子樹中序序列爲:{4,7,2};切割後的右子樹前序序列爲:{3,5,6,8},切割後的右子樹中序序列爲:{5,3,8,6}
對子樹分別使用同樣的方法分解

2.代碼

 function TreeNode(x) {
            this.val = x;
            this.left = null;
            this.right = null;
        }
        function reConstructBinaryTree(pre, vin) {

            if (pre.length == 0 || vin.length == 0) {
                return null;
            }
            pre = Array.from(pre);
            vin = Array.from(vin);
            let tree = new TreeNode(pre[0]);

            let mid = 0;
            for (let i = 0; i < vin.length; i++) {
                if (vin[i] == pre[0]) {
                    mid = i;
                    break;
                }
            }
            tree.left = reConstructBinaryTree(pre.slice(1, mid + 1), vin.slice(0, mid));
            tree.right = reConstructBinaryTree(pre.slice(mid + 1, pre.length), vin.slice(mid + 1, vin.length));
            return tree;
        }

3.測試

let a= [1, 2, 4, 7, 3, 5, 6, 8];    
        let b = [4,7, 2, 1, 5, 3, 8, 6];
       let sd =  reConstructBinaryTree(a, b);
       console.log(sd);

在這裏插入圖片描述

4.總結

1.通過二叉樹的前序和中序遍歷生成二叉樹最主要是考察前序中序遍歷的邏輯關係,前序找到根節點中序找到左右子樹。
2.通過遞歸循環生成每個節點。
3.js數組的slice用法 arr.slice(start,end)生成新的數組及左右子樹,對左右子樹再次遞歸直到每個葉子節點

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