题目描述
判断一棵二叉树是否为二叉搜索树,完全二叉树
实现思路
public static class Node {
int val;
Node left;
Node right;
public Node(int data) {
this.val = data;
}
}
二叉搜索树
二叉搜索树是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉搜索树在【中序遍历】的时候一定是升序的,因此可以通过【非递归中序遍历】时比较前后两个节点的值,判断是否符合一棵二叉树(二叉搜索树一般不会有两个相等的值)。
// 判断是否为二叉搜索树
public static boolean isBST(Node head) {
if (head == null) return true;
Stack<Node> stack = new Stack<>();
Node pre = null;
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (pre != null && head.val <= pre.val) return false;
pre = head;
head = head.right;
}
}
return true;
}
完全二叉树
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
不满足完全二叉树的两个条件
- 没有左孩子,有右孩子。不是完全二叉树
- 当一个节点只有左孩子,或者没有孩子的时候,后面遇到的节点必须都是叶节点(画图去理解)
// 判断是否为CBT
public static boolean isCBT(Node head) {
if (head == null) return true;
Queue<Node> queue = new LinkedList<>();
boolean leaf = false;
Node l = null;
Node r = null;
queue.offer(head);
while (!queue.isEmpty()) {
head = queue.poll();
l = head.left;
r = head.right;
if ((leaf && (l != null || r != null)) || (l == null && r != null)) {
return false;
}
if (l != null) {
queue.offer(l);
}
if (r != null) {
queue.offer(r);
}
if (l == null || r == null) {
leaf = true;
}
}
return true;
}