目录
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遍历最优