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)

原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13669850.html