1. 程式人生 > 實用技巧 >LeetCode筆記整理3 二叉樹中序遍歷 Morris中序遍歷

LeetCode筆記整理3 二叉樹中序遍歷 Morris中序遍歷

二叉樹的中序遍歷

使用棧模擬遞迴

var inorderTraversal = function(root) {
    var stack = []
    var res = []

    while(root || stack.length){
        while(root){
            stack.push(root)
            root = root.left
        }
        root = stack.pop()
        res.push(root.val)
        root = root.right
    }
    return res
};

Morris中序遍歷 LeetCode官方

思路與演算法

Morris遍歷演算法是另一種遍歷二叉樹的方法, 它能將非遞迴的中序遍歷空間複雜度將為O(1).

Morris遍歷演算法整體步驟如下(假設當前遍歷到的節點為X)

  1. 如果X無左孩子, 先將X的值加入答案陣列, 再訪問X的右孩子, 即X=X.right。
  2. 如果X有左孩子, 則找到X左子樹上最右的節點(即左子樹中序遍歷的最後一個節點, X在中序遍歷中的前驅節點), 我們記為predecessor(我稱之為R)。 根據r的右孩子是否為空, 進行如下操作。
    • 如果r的右孩子為空, 則將其右孩子指向X, 然後訪問X的左孩子, 即X=X.left
    • 如果r的右孩子不為空, 則此時其右孩子指向X, 說明我們已經遍歷完X的左子樹, 我們將R的右孩子置空, 將X的值加入答案陣列, 然後訪問X的右孩子, 即X=X.right
  3. 重複上述操作, 直至訪問完整棵樹
var inorderTraversal = function(root) {
    var res = []
    while(root){
        if(root.left){
            var r = root.left;
            while(r.right && root != r.right){
                r = r.right
            }
            if(!r.right){
                r.right = root
                root = root.left
            } 
            else {
                res.push(root.val)
                root = r.right
                root = root.right
            }
        } 
        else {
            res.push(root.val)
            root = root.right
        }
    }
    return res;
};

時間複雜度:)O(n),其中 n 為二叉搜尋樹的節點個數。Morris 遍歷中每個節點會被訪問兩次,因此總時間複雜度為 O(2n)=O(n) 空間複雜度:O(1)O(1)O(1)

作者:LeetCode-Solution 連結:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/ 來源:力扣(LeetCode)