平衡二叉树之AVL树(Adelson-Velsky and Landis Tree)简介及Java实现
[toc]
一、AVL树简介
在前面的内容中,我们已经介绍了平衡二叉树。其中提到了AVL树,这是一种非常著名的平衡二叉树。
在计算机科学中,AVL树(以发明者Adelson-Velsky和Landis命名)是一种自平衡二叉查找树。这是第一个发明类似自平衡机制的二叉树数据结构。在AVL树中,任何节点的两个子树的高度最多相差一个。如果在任何时候它们相差多于一个,则重新平衡以恢复此属性。查找,插入和删除在平均和最差情况下都需要$O(\log n)$时间,其中n是操作之前树中的节点数。插入和删除可能需要通过一个或多个树旋转来重新平衡树。
AVL树以其两位苏联发明家Georgy Adelson-Velsky和Evgenii Landis命名,他们在1962年的论文“An algorithm for the organization of information”中发表了这篇论文。
AVL树通常与红黑树进行比较,因为它们都支持相同的操作,并且对基本操作都是$O(\log n)$时间。对于查找密集型应用程序,AVL树比红黑树快,因为它们更严格地平衡。与红黑树相似,AVL树是高度平衡树。
二、平衡因子(Balance Factor)
在二叉树中,平衡因子(Balance Factor)是一种高度之差,它等于左子树的高度减去右子树的高度:
\text{BF(T)} = H_L - H_R
如果一个树是AVL树,那么它的平衡因子只能有三种取值,即0,1和-1。当平衡因子小于0,称为“left heavy”,大于0是“right-heavy”,等于0则是平衡的。
三、自平衡适应
前面已经说过了,保证树的平衡会大大提高搜索的效率。那么如何保证平衡就是不同自平衡树之间的差异了。AVL树保持自平衡的方式是通过旋转的方式。上述定义的平衡因子就是帮助我们判断是否需要进行平衡操作的信息,而AVL树的平衡操作主要包括单旋转和双旋转两种,前者分为左单旋和右单旋,而后者则分成左右旋转和右左旋转。
旋转操作发生在插入和删除操作中,因为插入和删除可能会破坏树的平衡状态。以插入为例,所有新加的元素都是叶子节点,叶子节点的左右子树高度都是0,因此平衡因子也是0,不存在平衡的需要。因此,需要平衡的节点是其父节点。平衡的操作取决于新加的元素是左叶子节点还是右叶子节点。如果是右叶子节点,那么父节点的平衡因子就要减1,否则加1。这个操作也会传导到爷爷节点一直到根节点。因此,这里也引申出了自平衡操作的两个基础:




