Javascript 中的 AVL 旋转

web developmentfront end technologyjavascript

为了保持自身平衡,AVL 树可以执行以下四种旋转 −

  • 左旋转
  • 右旋转
  • 左右旋转
  • 右左旋转

前两次旋转是单旋转,后两次旋转是双旋转。要拥有一棵不平衡的树,我们至少需要一棵高度为 2 的树。通过这棵简单的树,让我们逐一了解它们。

左旋转

如果一棵树变得不平衡,当一个节点插入到右子树的右子树中时,我们执行一次左旋转 −

左旋转

在我们的示例中,节点 A 已变得不平衡,因为一个节点插入到 A 的右子树的右子树中。我们通过将 A 设为 B 的左子树来执行左旋转。此旋转也称为 LL 旋转。让我们看看如何实现它 −

function rotationLL(node) {
let tmp = node.left;
node.left = tmp.right;
tmp.right = node;
return tmp;
}

右旋转

如果在左子树的左子树中插入节点,AVL 树可能会变得不平衡。然后树需要右旋转。

右旋转

如图所示,不平衡节点通过执行右旋转成为其左子节点的右子节点。这也称为 RR 旋转。让我们看看它在代码中的样子 −

function rotationRR(node) {
let tmp = node.right;
node.right = tmp.left;
tmp.left = node;
return tmp;
}

左右旋转

双重旋转是已经解释过的旋转版本的一个稍微复杂的版本。为了更好地理解它们,我们应该注意旋转时执行的每个动作。让我们首先检查如何执行左右旋转。左右旋转是左旋转和右旋转的组合。

状态动作
AVL Tree已将节点插入左子树的右子树。这使 C 成为不平衡节点。这些情况导致 AVL 树执行左右旋转。
Sub Tree我们首先对 C 的左子树进行左旋转。这使得 A 成为 B 的左子树。
左树节点 C 仍然不平衡,但是现在,这是因为左子树的左子树。
Own Left Tree我们现在将右旋转树,使 B 成为该子树的新根节点。 C 现在成为其自身左子树的右子树。
Tree Balanced树现在已平衡。

这也称为 LR 旋转,因为我们首先执行左旋转,然后执行右旋转。这可以使用前 2 种方法实现,如下所示 −

function rotationLR(node) {
node.left = rotationRR(node.left);
return rotationLL(node);
}

右-左旋转

第二种双旋转是右-左旋转。它是右旋转和左旋转的组合。

状态动作
平衡树已将节点插入右子树的左子树。这使得 A 成为一个不平衡节点,平衡因子为 2。
右子树首先,我们沿 C 节点执行右旋转,使 C 成为其自身左子树 B 的右子树。现在,B 成为 A 的右子树。
Unbalanced节点 A 仍然不平衡,因为它的右子树的右子树,需要左旋转。
Subtree通过使 B 成为子树的新根节点来执行左旋转。A 成为其右子树 B 的左子树。
Tree Balanced树现在平衡了。

这也称为 RL 旋转,因为我们首先执行右旋转,然后执行左旋转。可以使用前两种方法实现,如下所示 −

function rotationRL(node) {
node.right = rotationLL(node.right);
return rotationRR(node);
}

相关文章