📜  数据结构-平衡树

📅  最后修改于: 2020-10-15 01:02:52             🧑  作者: Mango

AVL树

AVL树由GM Adelson-Velsky和EM Landis于1962年发明。为了纪念其发明者,该树被命名为AVL。

可以将AVL树定义为高度平衡的二叉搜索树,其中每个节点都与一个平衡因子相关联,该平衡因子是通过从其左子树的高度中减去其右子树的高度来计算的。

如果每个节点的平衡因子在-1到1之间,则认为树是平衡的,否则,树将不平衡,需要平衡。

平衡系数(k)=高度(left(k))-高度(right(k))

如果任何节点的平衡因子为1,则表示左子树比右子树高一级。

如果任何节点的平衡因子为0,则表示左子树和右子树的高度相等。

如果任何节点的平衡因子为-1,则表示左子树比右子树低一级。

下图给出了一个AVL树。我们可以看到,与每个节点关联的平衡因子在-1和+1之间。因此,它是AVL树的一个示例。

复杂

Algorithm Average case Worst case
Space o(n) o(n)
Search o(log n) o(log n)
Insert o(log n) o(log n)
Delete o(log n) o(log n)

在AVL树上的操作

由于AVL树也是二分查找树的事实,因此所有操作的执行方式与二分查找树中执行的操作相同。搜索和遍历不会导致违反AVL树的属性。但是,插入和删除是可能违反此属性的操作,因此,需要重新研究它们。

SN Operation Description
1 Insertion Insertion in AVL tree is performed in the same way as it is performed in a binary search tree. However, it may lead to violation in the AVL tree property and therefore the tree may need balancing. The tree can be balanced by applying rotations.
2 Deletion Deletion can also be performed in the same way as it is performed in a binary search tree. Deletion may also disturb the balance of the tree therefore, various types of rotations are used to rebalance the tree.

为什么选择AVL树?

AVL树通过不使其偏斜来控制二进制搜索树的高度。在高度为h的二进制搜索树中,所有操作所需的时间为O(h)。但是,如果BST偏斜(即最坏的情况),则可以将其扩展为O(n)。通过将该高度限制为log n,AVL树将每个操作的上限设置为O(log n),其中n是节点数。

AVL旋转

仅在“平衡因子”不是-1、0和1的情况下,才在AVL树中执行旋转。基本上有以下四种旋转类型:

  • LL旋转:插入的节点在A的左子树的左子树中
  • RR旋转:插入的节点在A的右子树的右子树中
  • LR旋转:插入的节点在A的左子树的右子树中
  • RL旋转:插入的节点在A的右子树的左子树中

其中节点A是平衡因子不是-1、0、1的节点。

前两个旋转LL和RR是单旋转,接下来的两个旋转LR和RL是双旋转。为了使树木不平衡,最小高度必须至少为2,让我们了解每次旋转

1. RR旋转

当BST变得不平衡时,由于在A的右子树的右子树中插入了一个节点,因此我们执行RR旋转,RR旋转是逆时针旋转,应用于平衡因子为-2的节点下方的边缘

在上面的示例中,节点A具有平衡因子-2,因为在C右子树的右子树中插入了节点C。我们在A以下的边缘执行RR旋转。

2. LL旋转

当BST变得不平衡时,由于在C的左子树的左子树中插入了一个节点,所以我们执行LL旋转,LL旋转是顺时针旋转,应用于具有平衡因子2的节点下方的边缘。

在上面的示例中,节点C具有平衡因子2,因为在C左子树的左子树中插入了节点A。我们在A下方的边缘上执行LL旋转。

3.左旋转

上面已经解释过,双旋转比单旋转要难一些。 LR旋转= RR旋转+ LL旋转,即,首先在子树上执行RR旋转,然后在全树上执行LL旋转,通过全树,我们指的是平衡因子不为-1的插入节点路径中的第一个节点,0或1。

让我们非常清楚地了解每一步:

State Action
AVL Rotations A node B has been inserted into the right subtree of A the left subtree of C, because of which C has become an unbalanced node having balance factor 2. This case is L R rotation where: Inserted node is in the right subtree of left subtree of C
AVL Rotations As LR rotation = RR + LL rotation, hence RR (anticlockwise) on subtree rooted at A is performed first. By doing RR rotation, node A, has become the left subtree of B.
AVL Rotations After performing RR rotation, node C is still unbalanced, i.e., having balance factor 2, as inserted node A is in the left of left of C
AVL Rotations Now we perform LL clockwise rotation on full tree, i.e. on node C. node C has now become the right subtree of node B, A is left subtree of B
AVL Rotations Balance factor of each node is now either -1, 0, or 1, i.e. BST is balanced now.

4. RL旋转

正如已经讨论过的那样,双旋转比单旋转要难一些,这已经在上面进行了解释。 RL旋转= LL旋转+ RR旋转,即首先对子树执行LL旋转,然后对全树执行RR旋转,通过全树,我们指的是平衡因子不是-1的插入节点的路径中的第一个节点,0或1。

State Action
AVL Rotations A node B has been inserted into the left subtree of C the right subtree of A, because of which A has become an unbalanced node having balance factor – 2. This case is RL rotation where: Inserted node is in the left subtree of right subtree of A
AVL Rotations As RL rotation = LL rotation + RR rotation, hence, LL (clockwise) on subtree rooted at C is performed first. By doing RR rotation, node C has become the right subtree of B.
AVL Rotations After performing LL rotation, node A is still unbalanced, i.e. having balance factor -2, which is because of the right-subtree of the right-subtree node A.
AVL Rotations Now we perform RR rotation (anticlockwise rotation) on full tree, i.e. on node A. node C has now become the right subtree of node B, and node A has become the left subtree of B.
AVL Rotations Balance factor of each node is now either -1, 0, or 1, i.e., BST is balanced now.

问:构造具有以下元素的AVL树

H,I,J,B,A,E,C,F,D,G,K,L

1.插入H,I,J

在插入上述元素时,尤其是在H的情况下,由于H的平衡因子为-2,BST变得不平衡。由于BST向右倾斜,因此我们将在节点H上执行RR旋转。

结果平衡树为:

2.插入B,A

在插入上述元素时,尤其是在A的情况下,由于H和I的平衡因子为2,BST变得不平衡,我们考虑到最后插入的节点中的第一个节点,即H。由于H的BST左偏,我们将在节点H上执行LL旋转。

结果平衡树为:

3.插入E

在插入E时,由于I的平衡因子为2,BST变得不平衡,因为如果我们从E到I行驶,我们发现它插入了I的右子树的左子树中,我们将在节点I上执行LR旋转。LR = RR + LL旋转

3 a)我们首先在节点B上执行RR旋转

RR轮换后的结果树为:

3b)我们首先在节点I上执行LL旋转

LL旋转后的最终平衡树为:

4.插入C,F,D

在插入C,F,D时,由于B和H的平衡因子为-2,BST变得不平衡,因为如果我们从D到B行驶,我们会发现它插入了B的左子树的右子树中,我们将执行节点I上的RL旋转。RL= LL + RR旋转。

4a)我们首先在节点E上执行LL旋转

LL旋转后的结果树为:

4b)然后我们在节点B上执行RR旋转

RR旋转后的最终平衡树为:

5.插入G

在插入G时,由于H的平衡因子为2,BST变得不平衡,因为如果我们从G到H,我们发现它插入了H的右子树的左子树中,我们将在节点I上执行LR旋转。 LR = RR + LL旋转。

5 a)我们首先在节点C上执行RR旋转

RR轮换后的结果树为:

5 b)然后我们在节点H上执行LL旋转

LL旋转后的最终平衡树为:

6.插入K

插入K时,由于I的平衡因子为-2,BST变得不平衡。由于BST从I右倾斜到K,因此我们将在节点I上执行RR旋转。

RR旋转后的最终平衡树为:

7.插入L

插入L树时,由于每个节点的平衡因子现在为-1、0,+ 1,因此仍保持平衡。因此,树是平衡的AVL树