二叉树的常用类型(概念篇)
每一个类型判断 会有对应的类型特点分析,思路,java代码
二叉树有下面这几种类型(常用)
- 满二叉树
- 完全二叉树
- 二叉搜索树
- 普通二叉树
满二叉树:
满二叉树是一种二叉树,其中每个节点要么是叶子节点(没有子节点),要么同时有两个子节点。
完全二叉树:
完全二叉树是一种二叉树,除了最后一层外,每一层都被填满,而且最后一层的节点都集中在左侧。
二叉搜索树:
二叉搜索树(Binary Search Tree,BST)是一种二叉树,其中每个节点的值大于其左子树中的所有节点的值,同时小于其右子树中的所有节点的值,使得可以高效地进行查找、插入和删除操作。
普通二叉树:
只要这个树是二叉的,就是普通二叉树
如何判别二叉树的类型
满二叉树
特点:
节点个数=2^树的深度-1
每个节点要么是叶子节点(没有子节点),要么同时有两个子节点。
思路:
- 遍历每一个节点
- 在每一个节点上都检查左右节点
- 若左右节点都存在 或者 都不存在,说明该节点没问题,递归该节点的左右节点
- 否则说明不是满二叉树
- 在每一个节点上都检查左右节点
java代码:
//TreeNode.java
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
TreeNode() {}
public TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
//Tree.java
//isPerfectBinaryTree 判定该树是否为完美二叉树(满二叉树)
public boolean isPerfectBinaryTree(TreeNode root){
//满二叉树的定义即 节点个数=2^高度-1。
//也就是说每一个被遍历的节点要么有俩个子节点,要么没有子节点
//所以可以 遍历每一个节点,如果该节点满足上述其中一个就递归的检查它的left和right
if(root==null)return true;//空树 -> 也是满二叉树
if((root.left==null&&root.right==null)||(root.left!=null&&root.right!=null)){
//递归left和right
boolean leftIsPerfectBinaryTree = isPerfectBinaryTree(root.left);
boolean rightIsPerfectBinaryTree = isPerfectBinaryTree(root.right);
return leftIsPerfectBinaryTree&&rightIsPerfectBinaryTree;
}else {
return false;
}
}
完全二叉树
特点:
只有最后一层节点可能不完整,并且是从左到右的。
思路:
- 用BFS遍历整个二叉树
- 若发现一个节点为null,则后续的节点都应该为null
- 一旦发现一个null,说明不是完全二叉树
- 如果遍历完毕,说明是完全二叉树
java代码
//todo 是否是完全二叉树
public boolean isCompleteBinaryTree(TreeNode root){
//BFS遍历二叉树,若发现一个节点为null,则后续的节点都应该为null
// 若发现一个null,则说明不是完全二叉树。
if(root==null)return true;//空树也是 完全二叉树
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
boolean isHasNullNode=false;//用一个变量记录 是否已经出现null节点
//BFS遍历队列
while (!queue.isEmpty()){
TreeNode node = queue.poll();
if(node==null){
isHasNullNode=true;
}else {
//如果这个节点不为null,那么先检查isHasNullNode,若为true,说明不是完全二叉树
if(isHasNullNode){
return false;
}else{
//否则遍历node的left和right
queue.add(node.left);
queue.add(node.right);
}
}
}
//遍历完毕 一定为完全二叉树
return true;
}
二叉搜索树
特点:
节点的左节点的值<自己<右节点
思路1:根据min-max区间判断
- DFS遍历二叉树
- 检查当前节点值是否在一个min-max区间内,
- 若不在,说明不是二叉搜索树
- 若在,递归遍历left和right
- 检查当前节点值是否在一个min-max区间内,
java代码:
//todo 是否是二叉搜索树
public boolean isBinarySearchTree(TreeNode root){
//递归 ,根据[min,max]区间 判定BST
return isBinarySearchTree(root,null,null);
}
private boolean isBinarySearchTree(TreeNode root, Integer min, Integer max) {
if(root==null)return true;//空树也是二叉搜索树
//判断root的值是否在min-max之间
if ((min != null && root.val <= min) || (max != null && root.val >= max)) {
return false;
}
//递归检查 root的left和right
return isBinarySearchTree(root.left,min,root.val)&&isBinarySearchTree(root.right,root.val,max);
}
思路2:中序遍历
-
中序遍历二叉树
- 遍历过程中将当前节点的值添加到一个链表(数组中)
-
遍历这个结果数组/链表,若非递增,说明不是二叉搜索树
这个思路更容易,但不如思路1