package class14; import java.util.Stack; // 本题测试链接 : https://leetcode.com/problems/recover-binary-search-tree/ public class Code05_RecoverBinarySearchTree { // 不要提交这个类 public static class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int v) { val = v; } } // 如果能过leetcode,只需要提交这个方法即可 // 但其实recoverTree2才是正路,只不过leetcode没有那么考 public static void recoverTree(TreeNode root) { TreeNode[] errors = twoErrors(root); if (errors[0] != null && errors[1] != null) { int tmp = errors[0].val; errors[0].val = errors[1].val; errors[1].val = tmp; } } public static TreeNode[] twoErrors(TreeNode head) { TreeNode[] ans = new TreeNode[2]; if (head == null) { return ans; } TreeNode cur = head; TreeNode mostRight = null; TreeNode pre = null; TreeNode e1 = null; TreeNode e2 = 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 = null; } } if (pre != null && pre.val >= cur.val) { e1 = e1 == null ? pre : e1; e2 = cur; } pre = cur; cur = cur.right; } ans[0] = e1; ans[1] = e2; return ans; } // 以下的方法,提交leetcode是通过不了的,但那是因为leetcode的验证方式有问题 // 但其实!以下的方法,才是正路!在结构上彻底交换两个节点,而不是值交换 public static TreeNode recoverTree2(TreeNode head) { TreeNode[] errs = getTwoErrNodes(head); TreeNode[] parents = getTwoErrParents(head, errs[0], errs[1]); TreeNode e1 = errs[0]; TreeNode e1P = parents[0]; TreeNode e1L = e1.left; TreeNode e1R = e1.right; TreeNode e2 = errs[1]; TreeNode e2P = parents[1]; TreeNode e2L = e2.left; TreeNode e2R = e2.right; if (e1 == head) { if (e1 == e2P) { e1.left = e2L; e1.right = e2R; e2.right = e1; e2.left = e1L; } else if (e2P.left == e2) { e2P.left = e1; e2.left = e1L; e2.right = e1R; e1.left = e2L; e1.right = e2R; } else { e2P.right = e1; e2.left = e1L; e2.right = e1R; e1.left = e2L; e1.right = e2R; } head = e2; } else if (e2 == head) { if (e2 == e1P) { e2.left = e1L; e2.right = e1R; e1.left = e2; e1.right = e2R; } else if (e1P.left == e1) { e1P.left = e2; e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; } else { e1P.right = e2; e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; } head = e1; } else { if (e1 == e2P) { if (e1P.left == e1) { e1P.left = e2; e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1; } else { e1P.right = e2; e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1; } } else if (e2 == e1P) { if (e2P.left == e2) { e2P.left = e1; e2.left = e1L; e2.right = e1R; e1.left = e2; e1.right = e2R; } else { e2P.right = e1; e2.left = e1L; e2.right = e1R; e1.left = e2; e1.right = e2R; } } else { if (e1P.left == e1) { if (e2P.left == e2) { e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; e1P.left = e2; e2P.left = e1; } else { e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; e1P.left = e2; e2P.right = e1; } } else { if (e2P.left == e2) { e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; e1P.right = e2; e2P.left = e1; } else { e1.left = e2L; e1.right = e2R; e2.left = e1L; e2.right = e1R; e1P.right = e2; e2P.right = e1; } } } } return head; } public static TreeNode[] getTwoErrNodes(TreeNode head) { TreeNode[] errs = new TreeNode[2]; if (head == null) { return errs; } Stack stack = new Stack(); TreeNode pre = null; while (!stack.isEmpty() || head != null) { if (head != null) { stack.push(head); head = head.left; } else { head = stack.pop(); if (pre != null && pre.val > head.val) { errs[0] = errs[0] == null ? pre : errs[0]; errs[1] = head; } pre = head; head = head.right; } } return errs; } public static TreeNode[] getTwoErrParents(TreeNode head, TreeNode e1, TreeNode e2) { TreeNode[] parents = new TreeNode[2]; if (head == null) { return parents; } Stack stack = new Stack(); while (!stack.isEmpty() || head != null) { if (head != null) { stack.push(head); head = head.left; } else { head = stack.pop(); if (head.left == e1 || head.right == e1) { parents[0] = head; } if (head.left == e2 || head.right == e2) { parents[1] = head; } head = head.right; } } return parents; } // for test -- print tree public static void printTree(TreeNode head) { System.out.println("Binary Tree:"); printInOrder(head, 0, "H", 17); System.out.println(); } public static void printInOrder(TreeNode head, int height, String to, int len) { if (head == null) { return; } printInOrder(head.right, height + 1, "v", len); String val = to + head.val + to; int lenM = val.length(); int lenL = (len - lenM) / 2; int lenR = len - lenM - lenL; val = getSpace(lenL) + val + getSpace(lenR); System.out.println(getSpace(height * len) + val); printInOrder(head.left, height + 1, "^", len); } public static String getSpace(int num) { String space = " "; StringBuffer buf = new StringBuffer(""); for (int i = 0; i < num; i++) { buf.append(space); } return buf.toString(); } // 为了测试 public static boolean isBST(TreeNode head) { if (head == null) { return false; } Stack stack = new Stack(); TreeNode pre = null; while (!stack.isEmpty() || head != null) { if (head != null) { stack.push(head); head = head.left; } else { head = stack.pop(); if (pre != null && pre.val > head.val) { return false; } pre = head; head = head.right; } } return true; } public static void main(String[] args) { TreeNode head = new TreeNode(5); head.left = new TreeNode(3); head.right = new TreeNode(7); head.left.left = new TreeNode(2); head.left.right = new TreeNode(4); head.right.left = new TreeNode(6); head.right.right = new TreeNode(8); head.left.left.left = new TreeNode(1); printTree(head); System.out.println(isBST(head)); System.out.println("situation 1"); TreeNode head1 = new TreeNode(7); head1.left = new TreeNode(3); head1.right = new TreeNode(5); head1.left.left = new TreeNode(2); head1.left.right = new TreeNode(4); head1.right.left = new TreeNode(6); head1.right.right = new TreeNode(8); head1.left.left.left = new TreeNode(1); printTree(head1); System.out.println(isBST(head1)); TreeNode res1 = recoverTree2(head1); printTree(res1); System.out.println(isBST(res1)); System.out.println("situation 2"); TreeNode head2 = new TreeNode(6); head2.left = new TreeNode(3); head2.right = new TreeNode(7); head2.left.left = new TreeNode(2); head2.left.right = new TreeNode(4); head2.right.left = new TreeNode(5); head2.right.right = new TreeNode(8); head2.left.left.left = new TreeNode(1); printTree(head2); System.out.println(isBST(head2)); TreeNode res2 = recoverTree2(head2); printTree(res2); System.out.println(isBST(res2)); System.out.println("situation 3"); TreeNode head3 = new TreeNode(8); head3.left = new TreeNode(3); head3.right = new TreeNode(7); head3.left.left = new TreeNode(2); head3.left.right = new TreeNode(4); head3.right.left = new TreeNode(6); head3.right.right = new TreeNode(5); head3.left.left.left = new TreeNode(1); printTree(head3); System.out.println(isBST(head3)); TreeNode res3 = recoverTree2(head3); printTree(res3); System.out.println(isBST(res3)); System.out.println("situation 4"); TreeNode head4 = new TreeNode(3); head4.left = new TreeNode(5); head4.right = new TreeNode(7); head4.left.left = new TreeNode(2); head4.left.right = new TreeNode(4); head4.right.left = new TreeNode(6); head4.right.right = new TreeNode(8); head4.left.left.left = new TreeNode(1); printTree(head4); System.out.println(isBST(head4)); TreeNode res4 = recoverTree2(head4); printTree(res4); System.out.println(isBST(res4)); System.out.println("situation 5"); TreeNode head5 = new TreeNode(2); head5.left = new TreeNode(3); head5.right = new TreeNode(7); head5.left.left = new TreeNode(5); head5.left.right = new TreeNode(4); head5.right.left = new TreeNode(6); head5.right.right = new TreeNode(8); head5.left.left.left = new TreeNode(1); printTree(head5); System.out.println(isBST(head5)); TreeNode res5 = recoverTree2(head5); printTree(res5); System.out.println(isBST(res5)); System.out.println("situation 6"); TreeNode head6 = new TreeNode(4); head6.left = new TreeNode(3); head6.right = new TreeNode(7); head6.left.left = new TreeNode(2); head6.left.right = new TreeNode(5); head6.right.left = new TreeNode(6); head6.right.right = new TreeNode(8); head6.left.left.left = new TreeNode(1); printTree(head6); System.out.println(isBST(head6)); TreeNode res6 = recoverTree2(head6); printTree(res6); System.out.println(isBST(res6)); System.out.println("situation 7"); TreeNode head7 = new TreeNode(5); head7.left = new TreeNode(4); head7.right = new TreeNode(7); head7.left.left = new TreeNode(2); head7.left.right = new TreeNode(3); head7.right.left = new TreeNode(6); head7.right.right = new TreeNode(8); head7.left.left.left = new TreeNode(1); printTree(head7); System.out.println(isBST(head7)); TreeNode res7 = recoverTree2(head7); printTree(res7); System.out.println(isBST(res7)); System.out.println("situation 8"); TreeNode head8 = new TreeNode(5); head8.left = new TreeNode(3); head8.right = new TreeNode(8); head8.left.left = new TreeNode(2); head8.left.right = new TreeNode(4); head8.right.left = new TreeNode(6); head8.right.right = new TreeNode(7); head8.left.left.left = new TreeNode(1); printTree(head8); System.out.println(isBST(head8)); TreeNode res8 = recoverTree2(head8); printTree(res8); System.out.println(isBST(res8)); System.out.println("situation 9"); TreeNode head9 = new TreeNode(5); head9.left = new TreeNode(2); head9.right = new TreeNode(7); head9.left.left = new TreeNode(3); head9.left.right = new TreeNode(4); head9.right.left = new TreeNode(6); head9.right.right = new TreeNode(8); head9.left.left.left = new TreeNode(1); printTree(head9); System.out.println(isBST(head9)); TreeNode res9 = recoverTree2(head9); printTree(res9); System.out.println(isBST(res9)); System.out.println("situation 10"); TreeNode head10 = new TreeNode(5); head10.left = new TreeNode(3); head10.right = new TreeNode(6); head10.left.left = new TreeNode(2); head10.left.right = new TreeNode(4); head10.right.left = new TreeNode(7); head10.right.right = new TreeNode(8); head10.left.left.left = new TreeNode(1); printTree(head10); System.out.println(isBST(head10)); TreeNode res10 = recoverTree2(head10); printTree(res10); System.out.println(isBST(res10)); System.out.println("situation 11"); TreeNode head11 = new TreeNode(5); head11.left = new TreeNode(3); head11.right = new TreeNode(7); head11.left.left = new TreeNode(6); head11.left.right = new TreeNode(4); head11.right.left = new TreeNode(2); head11.right.right = new TreeNode(8); head11.left.left.left = new TreeNode(1); printTree(head11); System.out.println(isBST(head11)); TreeNode res11 = recoverTree2(head11); printTree(res11); System.out.println(isBST(res11)); System.out.println("situation 12"); TreeNode head12 = new TreeNode(5); head12.left = new TreeNode(3); head12.right = new TreeNode(7); head12.left.left = new TreeNode(8); head12.left.right = new TreeNode(4); head12.right.left = new TreeNode(6); head12.right.right = new TreeNode(2); head12.left.left.left = new TreeNode(1); printTree(head12); System.out.println(isBST(head12)); TreeNode res12 = recoverTree2(head12); printTree(res12); System.out.println(isBST(res12)); System.out.println("situation 13"); TreeNode head13 = new TreeNode(5); head13.left = new TreeNode(3); head13.right = new TreeNode(7); head13.left.left = new TreeNode(2); head13.left.right = new TreeNode(6); head13.right.left = new TreeNode(4); head13.right.right = new TreeNode(8); head13.left.left.left = new TreeNode(1); printTree(head13); System.out.println(isBST(head13)); TreeNode res13 = recoverTree2(head13); printTree(res13); System.out.println(isBST(res13)); System.out.println("situation 14"); TreeNode head14 = new TreeNode(5); head14.left = new TreeNode(3); head14.right = new TreeNode(7); head14.left.left = new TreeNode(2); head14.left.right = new TreeNode(8); head14.right.left = new TreeNode(6); head14.right.right = new TreeNode(4); head14.left.left.left = new TreeNode(1); printTree(head14); System.out.println(isBST(head14)); TreeNode res14 = recoverTree2(head14); printTree(res14); System.out.println(isBST(res14)); } }