概念:平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。(百度百科)
算法目的:判断一个二叉树是否是平衡二叉树。
算法要求:时间复杂度O(N),N为节点数目。
算法思路:解法的整体过程为二叉树的后序遍历,对任何一个节点node来说,先遍历node的左子树,遍历过程中收集两个信息,node的左子树是否为平衡二叉树,node的左子树最深到哪一层记为lH。如果发现node的左子树不是平衡二叉树,无须进行任何后续过程,此时返回什么已经不重要,因为已经发现整颗树不是平衡二叉树,退出遍历过程;如果node的左子树是平衡二叉树,再遍历node的右子树,过程类似于遍历左子树的过程,记录rH……。如果最终右子树也是平衡二叉树,就看rH 和 lH 差的绝对值是否大于1。
算法实现:节点的定义参考我的上一篇文章
package erchashu_bianli;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author zhengchao
*/
public class PinghengErchashu {
private final int[] array = { 1,2,3,4,5,6};
private static List<Node> nodeList = null;
//我们构建一个左拐二叉树的数据结构,假设节点数大于2,否则肯定是平衡二叉树。
public void createErChaTree() {
nodeList = new ArrayList<>();
// 将一个数组的值依次转换为Node节点
for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {
nodeList.add(new Node(array[nodeIndex]));
}
// 对前lastParentIndex-1个父节点按照父节点与孩子节点的数字关系建立二叉树
for (int parentIndex = 0; parentIndex < array.length - 2; parentIndex++) {
// 左孩子
nodeList.get(parentIndex).left = nodeList.get(parentIndex + 1);
}
nodeList.get(array.length - 2).left = nodeList.get(array.length - 1);
}
public static void main(String[] args){
PinghengErchashu pingheng = new PinghengErchashu();
pingheng.createErChaTree();
Node root = nodeList.get(0);
boolean isBalance = isBalance(root);
System.out.println("是否是平衡二叉树:"+isBalance);
}
public static boolean isBalance(Node head){
boolean[] res = new boolean[1];
res[0] = true;
getHeight(head,1,res);
return res[0];
}
public static int getHeight(Node head ,int level, boolean[] res){
if(head == null){
return level;
}
int lH = getHeight(head.left,level+1,res);
if(!res[0]){
return level;
}
int rH = getHeight(head.right,level+1,res);
if(!res[0]){
return level;
}
if(Math.abs(lH-rH)>1){
res[0] = false;
}
return Math.max(lH, rH);
}
}
在构建二叉树时,我们特意构造了一个非平衡二叉树。
运行结果:
run:
是否是平衡二叉树:false
成功构建 (总时间: 0 秒)
如果把
private final int[] array = { 1,2,3,4,5,6};
变成
private final int[] array = { 1,2};
运行结果:
run:
是否是平衡二叉树:true
成功构建 (总时间: 0 秒)