概要
前面分别介绍了AVL树”C语言版本”和”C++版本”,本章介绍AVL树的Java实现版本,它的算法与C语言和C++版本一样。内容包括:
- AVL树的介绍
- AVL树的Java实现
- AVL树的Java测试程序
AVL树的介绍
AVL树是高度平衡的而二叉树。它的特点是:AVL树中任何节点的两个子树的高度最大差别为1。
上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1;而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而以8为根节点的树的高度是1)。
AVL树的Java实现
1. 节点
1.1 节点定义
1 | public class AVLTree<T extends Comparable<T>> { |
AVLTree是AVL树对应的类,而AVLTreeNode是AVL树节点,它是AVLTree的内部类。AVLTree包含了AVL树的根节点,AVL树的基本操作也定义在AVL树中。AVLTreeNode包括的几个组成对象:
(01) key – 是关键字,是用来对AVL树的节点进行排序的。
(02) left – 是左孩子。
(03) right – 是右孩子。
(04) height – 是高度。
1.2 树的高度
1 | /* |
关于高度,有的地方将”空二叉树的高度是-1”,而本文采用维基百科上的定义:树的高度为最大层次。即空的二叉树的高度是0,非空树的高度等于它的最大层次(根的层次为1,根的子节点为第2层,依次类推)。
1.3 比较大小
1 | /* |
2.2 RR的旋转
理解了LL之后,RR就相当容易理解了。RR是与LL对称的情况!RR恢复平衡的旋转方法如下:
图中左边是旋转之前的树,右边是旋转之后的树。RR旋转也只需要一次即可完成。
RR的旋转代码
1 | /* |
2.3 LR的旋转
LR失去平衡的情况,需要经过两次旋转才能让AVL树恢复平衡。如下图:
第一次旋转是围绕”k1”进行的”RR旋转”,第二次是围绕”k3”进行的”LL旋转”。
LR的旋转代码
1 | /* |
2.4 RL的旋转
RL是与LR的对称情况!RL恢复平衡的旋转方法如下:
第一次旋转是围绕”k3”进行的”LL旋转”,第二次是围绕”k1”进行的”RR旋转”。
RL的旋转代码
1 | /* |
3. 插入
插入节点的代码
1 | /* |
4. 删除
删除节点的代码
1 | /* |
完整的实现代码
AVL树的实现文件(AVRTree.java)
1 | /** |
AVL树的测试程序(AVLTreeTest.java)
1 | /** |
AVL树的Java测试程序
AVL树的测试程序运行结果如下:
1 | == 依次添加: 3 2 1 4 5 6 7 16 15 14 13 12 11 10 8 9 |
下面,我们对测试程序的流程进行分析!
1. 新建AVL树
2. 依次添加”3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9” 到AVL树中。
2.01 添加3,2
添加3,2都不会破坏AVL树的平衡性。
2.02 添加1
添加1之后,AVL树失去平衡(LL),此时需要对AVL树进行旋转(LL旋转)。旋转过程如下:
2.03 添加4
添加4不会破坏AVL树的平衡性。
2.04 添加5
添加5之后,AVL树失去平衡(RR),此时需要对AVL树进行旋转(RR旋转)。旋转过程如下:
2.05 添加6
添加6之后,AVL树失去平衡(RR),此时需要对AVL树进行旋转(RR旋转)。旋转过程如下:
2.06 添加7
添加7之后,AVL树失去平衡(RR),此时需要对AVL树进行旋转(RR旋转)。旋转过程如下:
2.07 添加16
添加16不会破坏AVL树的平衡性。
2.08 添加15
添加15之后,AVL树失去平衡(RR),此时需要对AVL树进行旋转(RR旋转)。旋转过程如下:
2.09 添加14
添加14之后,AVL树失去平衡(RL),此时需要对AVL树进行旋转(RL旋转)。旋转过程如下:
2.10 添加13
添加13之后,AVL树失去平衡(RR),此时需要对AVL树进行旋转(RR旋转)。旋转过程如下:
2.11 添加12
添加12之后,AVL树失去平衡(LL),此时需要对AVL树进行旋转(LL旋转)。旋转过程如下:
2.12 添加11
添加11之后,AVL树失去平衡(LL),此时需要对AVL树进行旋转(LL旋转)。旋转过程如下:
2.13 添加10
添加10之后,AVL树失去平衡(LL),此时需要对AVL树进行旋转(LL旋转)。旋转过程如下:
2.14 添加8
添加8不会破坏AVL树的平衡性。
2.15 添加9
但是添加9之后,AVL树失去平衡(LR),此时需要对AVL树进行旋转(LR旋转)。旋转过程如下:
3. 打印树的信息
输出下面树的信息:
1 | 前序遍历: 7 4 2 1 3 6 5 13 11 9 8 10 12 15 14 16 |
4. 删除节点8
删除操作并不会造成AVL树的不平衡。
删除节点8之后,再打印该AVL树的信息。
1 | 高度: 5 |
- 原文链接:AVL树(三)之 Java的实现