搜索二叉树,左边子树小于父节点,右边子树的每个节点大于父节点。标准搜索二叉树不会有相等的节点
搜索二叉树进行中序遍历,应该是升序的,利用此特点来进行判断是否是搜索二叉树
方式一 递归
int preValue = Integer.MIN_VALUE;
private boolean checkBST1(Node head){
if (null == head){
return true;
}
boolean isLeftBST = checkBST1(head.left);
if(head.value < pre){
return false;
} else {
preValue = head.value;
}
return checkBST1(head.right);
}
方式二 递归2
private boolean checkBST2(Node head){
if (head == null) {
return true;
}
LinkedList<Node> list = new LinkedList<>();
process(head, list);
int preValue = Integer.MIN_VALUE;
for (Node node : list) {
if (preValue > node.value) {
return false;
}
preValue = node.value;
}
return true;
}
private void process(Node head, LinkedList<Node> list){
if (null == head){
return;
}
process(head.left,list);
list.add(head);
process(head.right,list);
}
方式三 非递归1
private static boolean checkBST3(Node head){
Stack<Node> stack = new Stack<>();
int preValue = Integer.MIN_VALUE;
while (!stack.isEmpty() || head != null){
if (null != head){
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (head.value < preValue){
return false;
} else {
preValue = head.value;
}
head = head.right;
}
}
return true;
}
方式四 树型DP(树型动态规划)
public static class ReturnData{
boolean isBST;
private int min;
private int max;
public ReturnData(boolean isBST, int min, int max) {
this.isBST = isBST;
this.min = min;
this.max = max;
}
}
//经典套路
/**
* 左树是否是搜索二叉树
* 右树是否是搜索二叉树
* 左树的最大值是否小于当前节点
* 右树的最小值是否大于当前节点
* @param head
* @return
*/
private static boolean checkBST4(Node head){
ReturnData returnData = process2(head);
System.out.println(returnData);
return returnData.isBST;
}
private static ReturnData process2(Node head){
if (null == head){
return null;//
}
ReturnData leftData = process2(head.left);
ReturnData rightData = process2(head.right);
boolean isBST = true;
int min = head.value;
int max = head.value;
if (null != leftData){
min = Math.min(min, leftData.min);
max = Math.max(max, leftData.max);
}
if (null != rightData){
min = Math.min(min, rightData.min);
max = Math.max(max, rightData.max);
}
if (null != leftData && (!leftData.isBST || leftData.max >= head.value)){
isBST = false;
}
if(null != rightData && (!rightData.isBST || rightData.min <= head.value)){
isBST = false;
}
// 两种判断方式都可以
// boolean isBST = false;
// if (
// (null != leftData ? (leftData.isBST && leftData.max < head.value) : true)
// &&
// (null != rightData ? (rightData.isBST && rightData.min > head.value) : true)
// ){
// isBST = true;
// }
return new ReturnData(isBST, min, max);
}
完整代码
public class IsBST {
public static class Node{
private int value;
private Node left;
private Node right;
public Node(int value) {
this.value = value;
}
}
private static int preValue = Integer.MIN_VALUE;
private static boolean checkBST(Node head){
if (null == head){
return true;
}
boolean isLeftBST = checkBST(head.left);
if (!isLeftBST){
return false;
}
if (head.value < preValue){
return false;
} else {
preValue = head.value;
}
return checkBST(head.right);
}
private static boolean checkBST2(Node head){
if (head == null) {
return true;
}
LinkedList<Node> list = new LinkedList<>();
process(head, list);
// int preValue = Integer.MIN_VALUE;
for (Node node : list) {
if (preValue > node.value) {
return false;
}
preValue = node.value;
}
return true;
}
private static void process(Node head, LinkedList<Node> list){
if (null == head){
return;
}
process(head.left,list);
list.add(head);
process(head.right,list);
}
private static boolean checkBST3(Node head){
Stack<Node> stack = new Stack<>();
// int preValue = Integer.MIN_VALUE;
while (!stack.isEmpty() || head != null){
if (null != head){
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (head.value < preValue){
return false;
} else {
preValue = head.value;
}
head = head.right;
}
}
return true;
}
public static class ReturnData{
private boolean isBST;
private int min;
private int max;
public ReturnData(boolean isBST, int min, int max) {
this.isBST = isBST;
this.min = min;
this.max = max;
}
@Override
public String toString() {
return "ReturnData{" +
"isBST=" + isBST +
", min=" + min +
", max=" + max +
'}';
}
}
//经典套路
/**
* 左树是否是搜索二叉树
* 右树是否是搜索二叉树
* 左树的最大值是否小于当前节点
* 右树的最小值是否大于当前节点
* @param head
* @return
*/
private static boolean checkBST4(Node head){
ReturnData returnData = process2(head);
System.out.println(returnData);
return returnData.isBST;
}
private static ReturnData process2(Node head){
if (null == head){
return null;//
}
ReturnData leftData = process2(head.left);
ReturnData rightData = process2(head.right);
boolean isBST = true;
int min = head.value;
int max = head.value;
if (null != leftData){
min = Math.min(min, leftData.min);
max = Math.max(max, leftData.max);
}
if (null != rightData){
min = Math.min(min, rightData.min);
max = Math.max(max, rightData.max);
}
if (null != leftData && (!leftData.isBST || leftData.max >= head.value)){
isBST = false;
}
if(null != rightData && (!rightData.isBST || rightData.min <= head.value)){
isBST = false;
}
// 两种判断方式都可以
// boolean isBST = false;
// if (
// (null != leftData ? (leftData.isBST && leftData.max < head.value) : true)
// &&
// (null != rightData ? (rightData.isBST && rightData.min > head.value) : true)
// ){
// isBST = true;
// }
return new ReturnData(isBST, min, max);
}
public static void main(String[] args) {
Node node = new Node(5);
node.left = new Node(3);
node.left.left = new Node(1);
node.left.right = new Node(4);
node.right = new Node(7);
node.right.left = new Node(6);
node.right.right = new Node(8);
// boolean bst = checkBST(node);
// System.out.println(bst);
// boolean bst2 = checkBST2(node);
// System.out.println(bst2);
// boolean bst3 = checkBST3(node);
// System.out.println(bst3);
boolean bst4 = checkBST4(node);
System.out.println(bst4);
}
}