Morris遍历二叉树

时间复杂度:O(N)
空间复杂度:O(1)

具体流程:
假设当前来到的节点记为cur

  • 如果cur无左孩子,cur向右移动(cur=cur.right)
  • 如果cur有左孩子,找到cur左子树的最右节点,记为mostright:
    1. 如果mostright的右指针指向空,让其指向cur,cur向左移动(cur=cur.left)
    2. 如果mostright的右指针指向cur,让其指向空,cur向右移动(cur=cur.right)

中序遍历,在最后一次到达该节点时打印

public static void morrisIn(Node head){
    if(head == null)
        return;
    Node cur = head;
    Node mostRight = null;
    while(cur != null){
        mostRight = cur.left;
        if(mostRight != null){
            while(mostRight.right != null && mostRight.right != cur){
                mostRight = mostRight.right;
            }
            if(mostRight.right == null){
                mostRight.right = cur;
                cur = cur.left;
                continue;
            } else { // mostRight.right = cur
                mostRight.right = null;
            }
        }
        System.out.print(cur.value + " ");
        cur = cur.right;
    }
    System.out.println();
}

先序遍历:在第一次到达该节点时打印

public static void morrisPre(Node head){
    if(head == null)
        return;
    Node cur = head;
    Node mostRight = null;
    while(cur != null){
        mostRight = cur.left;
        if(mostRight != null){
            while(mostRight.right != null && mostRight.right != cur){
                mostRight = mostRight.right;
            }
            if(mostRight.right == null){
                mostRight.right = cur;
                System.out.print(cur.value + " "); // 第一次来到这个节点
                cur = cur.left;
                continue;
            } else { // mostRight.right = cur
                mostRight.right = null;
            }
        } else {
            System.out.print(cur.value + " "); // 第一次来到这个节点
        }
        cur = cur.right;
    }
    System.out.println();
}

后序遍历:只关注能到达2次的节点,在第二次到达该节点时,逆序打印左子树右边界。最后打印整棵树的右边界。
逆序打印实现:类似反转链表打印后再恢复原样

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容