题目 判断一棵树是否是搜索二叉树、判断一棵树是否是完全二叉树
思路 搜索二叉树,即以树中任意节点为根节点的子树,其左子树的值永远比根小,右子树的值永远比根大。判断方法:若一棵树为搜索二叉树,则该树中序遍历后是依次递增的。设置一个变量init用于记录两个数比较的最小值,若当前数值比init小,即出现非递增情况,则该树非搜索二叉树。
完全二叉树,即前N-1层是满的,第N层是从左到右补全的树。判断方法:按层遍历。当前节点的孩子节点一共可分4种情况:左非空右非空,左空右非空,左非空右空,左空右空。若当前节点的左孩子节点为空而右孩子节点非空,则直接返回false,这不是完全二叉树;若当前节点的左孩子非空右孩子为空,或者左孩子为空右孩子也为空,则当前节点按层遍历的后续节点必须都是叶子节点,才能保证该树为完全二叉树。
package algorithm.section5;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class IsBSTAndCBT {
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int value){
this.value = value;
}
}
public static boolean isBST(Node head){
if (head == null) return true;
int init = Integer.MIN_VALUE;
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || head != null){
if (head != null){
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (head.value < init) return false;
else {
init = head.value;
head = head.right;
}
}
}
return true;
}
public static class ReturnData{
public int min;
public boolean isBST;
public ReturnData(int min, boolean isBST){
this.min = min;
this.isBST = isBST;
}
}
public static ReturnData isBST2(Node head){
int init = Integer.MIN_VALUE;
return BST(head, init);
}
public static ReturnData BST(Node head, int min){
if (head == null) return new ReturnData(min, true);
ReturnData left = BST(head.left, min);
if (left.min > head.value || !left.isBST) return new ReturnData(min, false);
min = head.value;
ReturnData right = BST(head.right, min);
if (right.min < head.value || !right.isBST) return new ReturnData(min, false);
min = right.min;
return new ReturnData(min, true);
}
public static boolean isCBT(Node head){
if (head == null) return true;
Queue<Node> queue = new LinkedList<>();
queue.offer(head);
while (!queue.isEmpty()){
Node node = queue.poll();
if (node.left == null && node.right != null) return false;
else if (node.left != null && node.right == null){
queue.offer(node.left);
return isLeaf(queue);
} else if (node.left == null && node.right == null) {
return isLeaf(queue);
} else {
queue.offer(node.left);
queue.offer(node.right);
}
}
return true;
}
public static boolean isLeaf(Queue<Node> queue){
while (!queue.isEmpty()){
Node flag = queue.poll();
if (flag.left != null || flag.right != null) return false;
else return true;
}
return true;
}
// for test -- print tree
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + 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 void main(String[] args) {
Node head = new Node(4);
head.left = new Node(2);
head.right = new Node(6);
head.left.left = new Node(1);
head.left.right = new Node(3);
head.right.right = new Node(9);
printTree(head);
System.out.println(isBST(head));
System.out.println(isBST2(head).isBST);
System.out.println(isCBT(head));
}
}