1. import java.util.ArrayList;
    2. /**
    3. * 判断树是否为搜索二叉树
    4. */
    5. public class Code02_IsBST {
    6. public static class Node {
    7. public int value;
    8. public Node left;
    9. public Node right;
    10. public Node(int data) {
    11. this.value = data;
    12. }
    13. }
    14. public static boolean isBST1(Node head) {
    15. if (head == null) {
    16. return true;
    17. }
    18. ArrayList<Node> arr = new ArrayList<>();
    19. in(head, arr);
    20. for (int i = 1; i < arr.size(); i++) {
    21. if (arr.get(i).value <= arr.get(i - 1).value) {
    22. return false;
    23. }
    24. }
    25. return true;
    26. }
    27. public static void in(Node head, ArrayList<Node> arr) {
    28. if (head == null) {
    29. return;
    30. }
    31. in(head.left, arr);
    32. arr.add(head);
    33. in(head.right, arr);
    34. }
    35. // *****************************************************************************
    36. /**
    37. * 主函数
    38. * @param head
    39. * @return
    40. */
    41. public static boolean isBST2(Node head) {
    42. // 在这里处理空,将下层的空放在这里处理
    43. if (head == null) {
    44. return true;
    45. }
    46. return process(head).isBST;
    47. }
    48. /**
    49. * 信息体定义
    50. */
    51. public static class Info {
    52. public boolean isBST;
    53. public int max;
    54. public int min;
    55. public Info(boolean i, int ma, int mi) {
    56. isBST = i;
    57. max = ma;
    58. min = mi;
    59. }
    60. }
    61. /**
    62. * 递归,所有过程一视同仁,必须返回信息体Info
    63. * @param x
    64. * @return
    65. */
    66. public static Info process(Node x) {
    67. // base case 对于节点为空时,如果不知道如何设置信息体中的值,可以返回空,然后在上游来处理这个空null;最大值和最小值知道如何设置,返回空
    68. if (x == null) {
    69. return null;
    70. }
    71. // 向左右树索取信息体信息
    72. Info leftInfo = process(x.left);
    73. Info rightInfo = process(x.right);
    74. // 加工自己的信息体内容
    75. // 1、加工 Info-max
    76. int max = x.value; // 首先设置自己值为最大值
    77. if (leftInfo != null) { // 如果左树不为空,将左树中的最大值和当前max比较
    78. max = Math.max(max, leftInfo.max);
    79. }
    80. if (rightInfo != null) { // 如果右树不为空,将右树中的最大值和当前max比较
    81. max = Math.max(max, rightInfo.max);
    82. }
    83. // 2、加工 Info-min 最小值
    84. int min = x.value;
    85. if (leftInfo != null) {
    86. min = Math.min(min, leftInfo.min);
    87. }
    88. if (rightInfo != null) {
    89. min = Math.min(min, rightInfo.min);
    90. }
    91. // 3、加工 Info-isBST,这时候由于null是没有判断的,放在上层判断,因此要充分考虑为空的情况。
    92. boolean isBST = true; //先假定是搜索二叉树,然后判断以下条件是否违反,违反了重置isBST
    93. if (leftInfo != null && !leftInfo.isBST) {
    94. isBST = false;
    95. }
    96. if (rightInfo != null && !rightInfo.isBST) {
    97. isBST = false;
    98. }
    99. if (leftInfo != null && leftInfo.max >= x.value) {
    100. isBST = false;
    101. }
    102. if (rightInfo != null && rightInfo.min <= x.value) {
    103. isBST = false;
    104. }
    105. return new Info(isBST, max, min);
    106. }
    107. //#########################对数器##############################################
    108. // for test
    109. public static Node generateRandomBST(int maxLevel, int maxValue) {
    110. return generate(1, maxLevel, maxValue);
    111. }
    112. // for test
    113. public static Node generate(int level, int maxLevel, int maxValue) {
    114. if (level > maxLevel || Math.random() < 0.5) {
    115. return null;
    116. }
    117. Node head = new Node((int) (Math.random() * maxValue));
    118. head.left = generate(level + 1, maxLevel, maxValue);
    119. head.right = generate(level + 1, maxLevel, maxValue);
    120. return head;
    121. }
    122. public static void main(String[] args) {
    123. int maxLevel = 4;
    124. int maxValue = 100;
    125. int testTimes = 1000000;
    126. for (int i = 0; i < testTimes; i++) {
    127. Node head = generateRandomBST(maxLevel, maxValue);
    128. if (isBST1(head) != isBST2(head)) {
    129. System.out.println("Oops!");
    130. }
    131. }
    132. System.out.println("finish!");
    133. }
    134. }