搜索二叉数:每一棵子树的根节点,左子树的值比根节点的值小,右子树的值比根节点的值大。
经典的搜索二叉树是没有重复值的。如果要放重复值,那么一定是在一个节点中用某种数据结构存放着,而不是产生多个值重复的节点。
用递归套路解决:
①目标:假设以 X 节点为根的二叉树是否为搜索二叉树;
②可能性:通过向左树获得某些信息,向右树获得某些信息的情况下来列举可能性;
③ X 是搜索二叉树的原则:
(1)X左树是搜索二叉树;
(2)X右树是搜索二叉树;
(3)X左树的最大值 < X节点的值;
(4)X节点的值 < X 右树的最小值;
所以对于每一个子树的根节点,只需要上面 4 个信息就能支持判断该子树是否为搜索二叉树。
整理可得,需要向左树获得信息:1. 是否为搜索二叉树;2. 最大值。
向右树获得信息:1. 是否为搜索二叉树;2. 最小值。
此时发现向左树和右树需要获得的信息不一样,怎么办呢?求全集!!
即是说,向左树和右树都需要获得信息包括(1)是否为搜索二叉树;(2)最大值;(3)最小值。
public static boolean isBST2(Node head) {
if (head == null) {
return true;
}
return process(head).isBST;
}
public static class Info {
public boolean isBST;
public int max;
public int min;
public Info(boolean i, int ma, int mi) {
isBST = i;
max = ma;
min = mi;
}
}
public static Info process(Node x) {
if (x == null) {
return null;
}
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int max = x.value;
if (leftInfo != null) {
max = Math.max(max, leftInfo.max);
}
if (rightInfo != null) {
max = Math.max(max, rightInfo.max);
}
int min = x.value;
if (leftInfo != null) {
min = Math.min(min, leftInfo.min);
}
if (rightInfo != null) {
min = Math.min(min, rightInfo.min);
}
boolean isBST = true;
if (leftInfo != null && !leftInfo.isBST) {
isBST = false;
}
if (rightInfo != null && !rightInfo.isBST) {
isBST = false;
}
if (leftInfo != null && leftInfo.max >= x.value) {
isBST = false;
}
if (rightInfo != null && rightInfo.min <= x.value) {
isBST = false;
}
return new Info(isBST, max, min);
}