算法学习笔记----Morris遍历

目录

Morris遍历

morris遍历改先序遍历

morris遍历改中序遍历

morris遍历改后序遍历

判断一颗树是否是搜索二叉树

使用场景


Morris遍历

public static void morris(Node root) {
        
        if(root == null) {
            return;
        }
        
        Node cur = root;
        Node moreRight = null;
        while(cur != null) {
            moreRight = cur.left;
            
            if(moreRight != null) {
                while(moreRight.right != null && moreRight.right != cur) {
                    moreRight = moreRight.right;
                }
                if(moreRight.right == null) {//第一次来到左子树的最右节点
                    moreRight.right = cur;
                    cur = cur.left;
                    continue;
                }else {//不为空说明指向cur 为第二次来到该节点
                    moreRight.right = null;
                }
            }
            cur = cur.right;
        }
    }

morris遍历改先序遍历
//morris先序遍历:第一次来到当前节点时打印
    public static void morrisPre(Node root) {
        if(root == null) {
            return;
        }
        
        Node cur = root;
        Node moreRight = null;
        while(cur != null) {
            moreRight = cur.left;
            
            if(moreRight != null) {
                while(moreRight.right != null && moreRight.right != cur) {
                    moreRight = moreRight.right;
                }
                if(moreRight.right == null) {//第一次来到左子树的最右节点
                    System.out.println(cur.value);
                    moreRight.right = cur;
                    cur = cur.left;
                    continue;
                }else {//不为空说明指向cur 为第二次来到该节点
                    moreRight.right = null;
                }
            }else {//无左子树的节点无法来到第二次 打印
                System.out.println(cur.value);
            }
            cur = cur.right;
        }
    }

morris遍历改中序遍历
//morris中序遍历 只来一次的节点直接打印 来两次的节点第二次打印
    public static void morrisIn(Node root) {
        
        if(root == null) {
            return;
        }
        
        Node cur = root;
        Node moreRight = null;
        while(cur != null) {
            moreRight = cur.left; 
            
            if(moreRight != null) {
                while(moreRight.right != null && moreRight.right != cur) {
                    moreRight = moreRight.right;
                }
                if(moreRight.right == null) {//第一次来到左子树的最右节点
                    moreRight.right = cur;
                    cur = cur.left;
                    continue;
                }else {//不为空说明指向cur 为第二次来到该节点
                    moreRight.right = null;
                }
            }
            System.out.println(cur.value);
            cur = cur.right;
        }
    }

morris遍历改后序遍历
//morris后序遍历 第二次来到节点时 打印该节点左树的右边界
    public static void morrisPos(Node root) {
        
        if(root == null) {
            return;
        }
        
        Node cur = root;
        Node moreRight = null;
        while(cur != null) {
            moreRight = cur.left;
            
            if(moreRight != null) {
                while(moreRight.right != null && moreRight.right != cur) {
                    moreRight = moreRight.right;
                }
                if(moreRight.right == null) {//第一次来到左子树的最右节点
                    moreRight.right = cur;
                    cur = cur.left;
                    continue;
                }else {//不为空说明指向cur 为第二次来到该节点
                    moreRight.right = null;
                    printEdge(cur.left);
                }
            }
            cur = cur.right;
        }
        printEdge(root);
        System.out.println();
    }
    
    //逆序打印以root为根的右边界
    public static void printEdge(Node root) {
        root = reverseEdge(root);
        Node cur = root;
        while(cur != null) {
            System.out.print(cur.right.value + " ");
            cur = cur.right;
        }
        reverseEdge(root);
    }
    
    //将树的边逆序 同单链表逆序
    public static Node reverseEdge(Node head) {
        Node pre = null;
        Node next = null;
        
        while(head != null) {
            next = head.right;
            head.right = pre;
            pre = next;
            head = next;
        }
        
        return pre;
    }

判断一颗树是否是搜索二叉树
//判断一棵树是否是搜索二叉树
    public static boolean isBST(Node root) {
        
        if(root == null) {
            return true;
        }
        
        Node cur = root;
        Node moreRight = null;
        int pre  = Integer.MIN_VALUE;
        while(cur != null) {
            moreRight = cur.left;
            
            if(moreRight != null) {
                while(moreRight.right != null && moreRight.right != cur) {
                    moreRight = moreRight.right;
                }
                if(moreRight.right == null) {//第一次来到左子树的最右节点
                    moreRight.right = cur;
                    cur = cur.left;
                    continue;
                }else {//不为空说明指向cur 为第二次来到该节点
                    moreRight.right = null;
                }
            }
            if(cur.value <= pre) {
                return false;
            }
            pre = cur.value;
            cur = cur.right;
        }
        return true; 
    }

使用场景

二叉树递归套路和morris遍历什么时候使用才是最优解?

需要第三次信息的强整合,要左树信息、右树信息再整合返回自己的信息时用二叉树递归套路。

如果不需要第三次信息的强整合,morris遍历最优

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值