在没有旋转的情况下保持avl树平衡
Keeping avl tree balanced without rotations
B树和AVL树一样是自平衡树。 HERE 我们可以看到如何使用左右旋转来保持 AVL 树的平衡。
而HERE是一个link,解释了B树中的插入。如果我没记错的话,这种插入技术不涉及任何旋转以保持树平衡。因此它看起来更简单。
问题:是否有任何类似的(或任何其他不使用旋转的技术)来保持 avl 树平衡?
答案是……是也不是。
B 树不需要执行轮换,因为它们在可以将多少不同的键打包到一个节点上有一些松弛。当您向 B 树中添加越来越多的键时,您可以通过将这些键吸收到节点本身来避免树变得不平衡。
二叉树没有这种奢侈。如果您将一个键插入二叉树,在所有情况下它都会将该树中某个分支的高度增加 1,因为该键需要进入它自己的节点。旋转通过确保如果某些树枝长得太多,该高度会被混入树的其余部分,从而阻止树的整体生长。
大多数平衡的 BST 都有某种涉及轮换的再平衡策略,但并非所有人都这样做。 scapegoat tree 是一种不直接涉及旋转的策略,它通过从主树中撕下巨大的子树,优化重建它们,然后将子树粘回主树来重新平衡。这种方法技术上不涉及任何旋转,是实现平衡树的一种非常干净的方法。
就是说 - 最 space 最有效的替罪羊树实现确实使用旋转将不平衡的树转换为完美平衡的树。您 没有 使用旋转来执行此操作,但如果 space 很短,这可能是最好的方法。
希望对您有所帮助!
旋转可以变得简单(如果你只需要简单的话)。
如果插入流量还剩,余额-1就是红灯
如果插入流量是对的,余额1就是红灯
这是标准化基本 AVL 平衡的(简化的)粗粒度(2 进舍入):
{left,even,right} ~ {low,even,high} ~ {green,green,red}
走插入路线,旋转每个红灯(插入前)。如果下一盏灯是绿灯,你只需旋转红灯 1 或 2 次即可。您可能必须在每次旋转之前重新平衡下一个子树,因为内部子树是不变的。这很简单,但需要很长时间。每次旋转之前,您必须在绿灯下移动。您可以随时将绿灯向下移动到根部,并且可以旋转树顶以产生新的绿灯。
红灯旋转自然向下移动绿灯。
此时,您只有插入绿灯。
这种朴素方法的成本结构在拓扑上被简化为
df(h)/dh=∫f(h)dh
例如sin(h),sinh(h)等
B树和AVL树一样是自平衡树。 HERE 我们可以看到如何使用左右旋转来保持 AVL 树的平衡。
而HERE是一个link,解释了B树中的插入。如果我没记错的话,这种插入技术不涉及任何旋转以保持树平衡。因此它看起来更简单。
问题:是否有任何类似的(或任何其他不使用旋转的技术)来保持 avl 树平衡?
答案是……是也不是。
B 树不需要执行轮换,因为它们在可以将多少不同的键打包到一个节点上有一些松弛。当您向 B 树中添加越来越多的键时,您可以通过将这些键吸收到节点本身来避免树变得不平衡。
二叉树没有这种奢侈。如果您将一个键插入二叉树,在所有情况下它都会将该树中某个分支的高度增加 1,因为该键需要进入它自己的节点。旋转通过确保如果某些树枝长得太多,该高度会被混入树的其余部分,从而阻止树的整体生长。
大多数平衡的 BST 都有某种涉及轮换的再平衡策略,但并非所有人都这样做。 scapegoat tree 是一种不直接涉及旋转的策略,它通过从主树中撕下巨大的子树,优化重建它们,然后将子树粘回主树来重新平衡。这种方法技术上不涉及任何旋转,是实现平衡树的一种非常干净的方法。
就是说 - 最 space 最有效的替罪羊树实现确实使用旋转将不平衡的树转换为完美平衡的树。您 没有 使用旋转来执行此操作,但如果 space 很短,这可能是最好的方法。
希望对您有所帮助!
旋转可以变得简单(如果你只需要简单的话)。
如果插入流量还剩,余额-1就是红灯
如果插入流量是对的,余额1就是红灯
这是标准化基本 AVL 平衡的(简化的)粗粒度(2 进舍入):
{left,even,right} ~ {low,even,high} ~ {green,green,red}
走插入路线,旋转每个红灯(插入前)。如果下一盏灯是绿灯,你只需旋转红灯 1 或 2 次即可。您可能必须在每次旋转之前重新平衡下一个子树,因为内部子树是不变的。这很简单,但需要很长时间。每次旋转之前,您必须在绿灯下移动。您可以随时将绿灯向下移动到根部,并且可以旋转树顶以产生新的绿灯。
红灯旋转自然向下移动绿灯。
此时,您只有插入绿灯。
这种朴素方法的成本结构在拓扑上被简化为
df(h)/dh=∫f(h)dh
例如sin(h),sinh(h)等