1.先定义一个节点的对象
package com.wang.tree;
/**
* 二叉树节点类
* @description
* @author wang
* @date 2018年11月20日
*/
public class TreeNode {
private int data;
private TreeNode leftNode;
private TreeNode rightNode;
private TreeNode parentNode;
public TreeNode() {
super();
// TODO 自动生成的构造函数存根
}
public TreeNode(int data) {
super();
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public TreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
public TreeNode getRightNode() {
return rightNode;
}
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
public TreeNode getParentNode() {
return parentNode;
}
public void setParentNode(TreeNode parentNode) {
this.parentNode = parentNode;
}
}
说明:定义parentNode父节点是为了在后面向树中插入数据之后,旋转调整用的。还可以定义 宽度,层次等属性。
2.定义AVL工具类,定义检测二叉树是否平衡的方法(两种方法实现,迭代和非迭代)
package com.wang.tree;
/**
* 二叉平衡树(AVL树)
* @description
* @author wang
* @date 2018年11月20日
*/
public class AVLTreeUtil {
/**
* 判断二叉树是否是平衡二叉树
* 缺点:重复的计算子树的高度
* @param node (root根节点,迭代遍历)
* @return
*/
public static boolean isBalance=true;
public static boolean isBalanced(TreeNode node){
//如果是空树,则是平衡二叉树
if(null == node){
return true;
}
//如果不为空
//左子树或者右子树为空,则高度差肯定小于2则为平衡二叉树
if(null == node.getLeftNode() || null == node.getRightNode()){
return true;
}
//如果左子树或者右子树都不为空,则比较高度差
// 计算得到左子树的深度
int leftDepth = treeDepth(node.getLeftNode());
// 计算得到右子树的深度
int rightDepth = treeDepth(node.getRightNode());
// 如果高度差大于1,不满足平衡二叉的条件
if (Math.abs(leftDepth - rightDepth) > 1) {
return false;
}
// 判断左子树和右子树是否满足平衡二叉树的条件
return isBalanced(node.getLeftNode()) && isBalanced(node.getRightNode());
}
public static int treeDepth(TreeNode node){
if(null == node){
return 0;
}
//计算左子树的深度
int left = treeDepth(node.getLeftNode());
//计算右子树的深度
int right = treeDepth(node.getRightNode());
// 树root的深度=路径最长的子树深度 + 1
return left >= right ? (left + 1) : (right + 1);
}
/**
* 可以用后序遍历,从下到上遍历如果子树中任一不满足条件返回 false<p>
* 否则返回 true 这样每个节点的高度只会算一次
* @param node
* @return
*/
public static boolean isBalanced1(TreeNode node){
treeDepth1(node);
return isBalance;
}
public static int treeDepth1(TreeNode root){
if(root==null)
return 0;
int left=treeDepth1(root.getLeftNode());
//左子树高度
int right=treeDepth1(root.getRightNode());
//右子树高度
if(Math.abs(left-right)>1)
{
isBalance=false;
//只要有一个子树的左右子树的高度绝对值大于 1 isBalance=false
}
return Math.max(left, right)+1;
}
}
3.编写测试类来验证
package com.wang.tree;
/**
*
* @description 二叉平衡树测试类
* @author wang
* @date 2018年11月21日
*/
public class AVLTreeTest {
public static void main(String[] args) {
TreeNode root = new TreeNode(6);
TreeNode node2 = new TreeNode(4);
TreeNode node3 = new TreeNode(8);
TreeNode node4 = new TreeNode(1);
TreeNode node5 = new TreeNode(5);
TreeNode node6 = new TreeNode(9);
TreeNode node7 = new TreeNode(2);
root.setLeftNode(node2);
root.setRightNode(node3);
node2.setParentNode(root);
node2.setLeftNode(node4);
node2.setRightNode(node5);
node3.setParentNode(root);
node3.setRightNode(node6);
node4.setRightNode(node7);
node7.setParentNode(node4);
//答案应该是true
System.out.println(AVLTreeUtil.isBalanced(root));
TreeNode node8 = new TreeNode(3);
node7.setRightNode(node8);
//再加一层的话,应该是false
System.out.println(AVLTreeUtil.isBalanced(root));
}
}
打印结果:
true
false