当树的结构发生变化时(如插入结点或删除结点),我们需要调整树使其重新满足AVL树的性质。可以通过单旋转或者双旋转来实现调整。
假设需要调整平衡的结点是X。因为任何一个结点至多有两个孩子,而且失衡高度要求X的两棵子树的高度差为2,我们可以发现失衡有4种情况:
1.插入发生在X的左孩子的左子树中。 2.插入发生在X的左孩子的右子树中。 3.插入发生在X的右孩子的左子树中。 4.插入发生在X的右孩子的右子树中。
在下面的情况中,在结点X处,AVL树的性质不被满足。旋转没必要在树根处进行。通常,我们从被插入的结点开始,沿着向上的分支访问树,更新路径上每个结点的平衡信息。 将7插入原始AVL树之后,结点9变得不平衡了。所以我们需要在结点9处进行单LL旋转。
在下面的情况中,在结点X处,AVL树的性质不被满足。 将29插入原始AVL树之后,结点15变得不平衡了。所以我们需要在结点15处进行单RR旋转。
针对情况2和情况3,单旋转不能解决问题。我们需要执行两次旋转。 将、插入结点7产生情况2的场景,最右侧树是经过两次旋转后得到的树。
与情况2类似,我们需要执行两次旋转处理该情况。 插入结点5产生情况3的场景,最右侧的树是经过两次旋转后得到的树。
由于AVL树多数情况是用于查找的,所以删除操作就由懒惰删除来代替。一般删除操作多的不会用到AVL树。
AVL树(1)——简介 AVL树(2)——插入与旋转调整 AVL树(3)——C++实现