非递归中序遍历二叉树总结(2种方法)

算法 非递归中序遍历二叉树总结(2种方法)

@author:Jingdai
@date:2020.12.03

传送门

方法1

先序遍历是第一次遇到该节点遍历;中序是第二次遇到该节点遍历;而后序是第三次遇到该节点遍历。非递归用栈进行遍历,第一次遇到就是压栈时,第二次是弹栈时,所以中序遍历应该弹栈的时候进行遍历。弹栈后代表弹栈节点及其左子树已经遍历完了,所以此时将弹栈节点的右子节点压栈,对其右子树进行同样的操作。代码如下。

public static void inOrderTraverse(TreeNode root) {
    
    

    TreeNode p = root;
    LinkedList<TreeNode> stack = new LinkedList<>();

    while (p != null || stack.size() != 0) {
    
    
        while (p != null) {
    
    
            stack.push(p);
            p = p.left;
        }
        p = stack.pop();
        System.out.println(p.val);
        p = p.right;
    }
}

其实仔细观察代码的话会发现其实中序和先序代码除了遍历(这里就是输出语句)的位置不一样,其余的代码完全一样,所以先序和中序会一种,另一种也就会了。ps:先序可以看我上一篇的总结

方法2 Morris方法

Morris方法是为了将遍历的空间复杂度从 O(h) 降为 O(1),如果对Morris遍历过程有问题的可以看我前一篇先序遍历的总结,这里直接上代码。

public static void inOrderTraverse(TreeNode root) {
    
    

    TreeNode cur = root;
    TreeNode rightmost = null;

    while (cur != null) {
    
    
        if (cur.left != null) {
    
    
            rightmost = cur.left;
            while (rightmost.right != null && rightmost.right != cur) {
    
    
                rightmost = rightmost.right;
            }
            if (rightmost.right == null) {
    
     // first
                rightmost.right = cur;
                cur = cur.left;
            } else {
    
     // second
                rightmost.right = null;
                System.out.println(cur.val);
                cur = cur.right;
            }
        } else {
    
    
            System.out.println(cur.val);
            cur = cur.right;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41512783/article/details/110583191