一、简介:
需要注意的是,平衡二叉树是建立在二叉排序树的基础之上的。
是一种对二叉排序树的优化,以免出现下面类似的问题:
平衡二叉树(AVL),其中 AV和L是发明者的名字首字母。
二、分布代码:
很多代码可以复用前面的二叉排序树中的,下面列出新增的代码:
1、求AVL高度(Node类中)
测试一下:
输出:
可见,树的高度为4,而其右子树的高度为3,左子树的高度为1.
3 - 1 = 2 大于 1了,这就不是平衡二叉树了。
为了使其变成平衡二叉树,我们需要对其进行左旋转。
左旋转的目的:降低右子树的高度。
左旋转图解:
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
2、左旋转代码(Node类中):
在添加结点的方法中,增加一个判断语句:
测试:
3、右旋转
与左旋转类似:
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
在Node类中,写一个右旋转方法:
在Node的add方法内,再加上这句:
测试一下:
可以发现根节点已经由10变成8了,右旋转成功。
4、双旋转★
前面两个数列,进行单旋转(一次旋转)就可以将非平衡二叉树转成平衡二叉树,但在某些情况下,单旋转不能完成平衡二叉树的转换。比如:
int [] arr = {
10 , 11 , 7 , 6 , 8 , 9 };
运行之前代码,并没有转成 AVL 树:
原因图解:
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
先进行左旋转,再进行右旋转,成功转成 AVL 树。
在原先的add方法里面,增加一些代码即可:
测试:
输出:
三、完整代码
package com.huey.avl;
public class AVLTreeDemo {
public static void main(String[] args) {
// int[] arr = { 4, 3, 6, 5, 7, 8 };
// int[] arr = { 10, 12, 8, 9, 7, 6 };
int[] arr = {
10, 11, 7, 6, 8, 9 };
// 创建一个AVLTree对象
AVLTree avlTree = new AVLTree();
// 添加结点
for (int i = 0; i < arr.length; i++) {
avlTree.add(new Node(arr[i]));
}
// 遍历
System.out.println("中序遍历~");
avlTree.infixOrder();
// System.out.println("在没有做平衡处理前~");
// System.out.println("树的高度:" + avlTree.getRoot().height());// 4
// System.out.println("树的左子树的高度:" + avlTree.getRoot().leftHeight());// 1
// System.out.println("树的右子树的高度:" + avlTree.getRoot().rightHeight());// 3
System.out.println("在做平衡处理后~");
System.out.println("树的高度:" + avlTree.getRoot().height());// 3
System.out.println("树的左子树的高度:"