课程笔记:Morris遍历

Morris遍历

Morris遍历法能以O(1)的空间复杂度和O(n)的时间复杂度实现二叉树的三种遍历,其中不使用栈或额外空间

常用的二叉树递归遍历中,要回到节点三次

public static void process(Node head){
    if(head==null)
    return;
    //先序遍历
    process(head.left);
    //中序遍历
    process(head.right);
    //后序遍历
}


而在Morris遍历中,有左子树的节点来到两次,没有的仅一次。通过记录左子树的mostRight节点指向谁来判断来到第几次

public static void morris(Node head) {
        if (head == null) {
            return;
        }
        Node cur1 = head;
        Node cur2 = null;
        while (cur1 != null) {
            cur2 = cur1.left;
            if (cur2 != null) {  //当前节点存在左孩子时
                while (cur2.right != null && cur2.right != cur1) {  //2找到左子树的最右节点
                    cur2 = cur2.right;
                }
                if (cur2.right == null) {  //2.1最右节点的右指针指向空,即第一次来到节点
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                } else {  //2.2最右节点的右指针指向cur1,即第二次来到节点
                    cur2.right = null;
                }
            }
            //System.out.print(cur1.value + " ");
            cur1 = cur1.right;  //1节点向右移动
        }
    }

 

先序实现:只打印第一次来到的节点

中序实现:能来到两次的节点第二次打印,不能的直接打印

后序实现:对能来到两次的节点,逆序打印其左子树的右边界

public static void printEdge(Node head) {//后续遍历逆序打印左子树的右边界
        Node tail = reverseEdge(head);
        Node cur = tail;
        while (cur != null) {
            System.out.print(cur.value + " ");
            cur = cur.right;
        }
        reverseEdge(tail);
}

public static Node reverseEdge(Node from) {//返回
        Node pre = null;
        Node next = null;
        while (from != null) {
            next = from.right;
            from.right = pre;
            pre = from;
            from = next;
        }
        return pre;
}

注意:Morris遍历只能解决回到节点第二次之内的二叉树问题

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值