Algorithm 平衡二叉树(AVL)

Algorithm 平衡二叉树(AVL),algorithm,computer-science,binary-tree,theory,avl-tree,Algorithm,Computer Science,Binary Tree,Theory,Avl Tree,好的,这是另一个在理论领域为CS的家伙周围 在90年代,我在实施BST方面做得相当好。我唯一无法理解的是平衡二叉树(AVL)算法的复杂性 你们能在这方面帮助我吗?我认为在这里发布节点平衡算法的完整代码并不好,因为它们变得相当大。但是,Wikipedia上的文章包含了该算法的完整C实现,上的文章也有一些指向高质量实现的链接 这两种实现对于大多数通用场景来说已经足够了。替罪羊树可能有最简单的平衡确定算法。如果任何插入导致新节点太深,它将通过查看重量平衡而不是高度平衡来查找要在其周围重新平衡的节点。关

好的,这是另一个在理论领域为CS的家伙周围

在90年代,我在实施BST方面做得相当好。我唯一无法理解的是平衡二叉树(AVL)算法的复杂性


你们能在这方面帮助我吗?

我认为在这里发布节点平衡算法的完整代码并不好,因为它们变得相当大。但是,Wikipedia上的文章包含了该算法的完整C实现,上的文章也有一些指向高质量实现的链接


这两种实现对于大多数通用场景来说已经足够了。

替罪羊树可能有最简单的平衡确定算法。如果任何插入导致新节点太深,它将通过查看重量平衡而不是高度平衡来查找要在其周围重新平衡的节点。关于是否在删除时重新平衡的规则也很简单。它不会在节点中存储任何神秘信息。要证明它是正确的要复杂得多,但你不需要这些来理解算法

然而,与AVL不同的是,它并非始终保持高度平衡。与红黑一样,它的不平衡是有界的,但与红黑不同,它可以通过一个参数进行调节,因此在大多数实际应用中,它看起来就像你需要的那样平衡。不过,我怀疑如果你把它调得太紧,那么在最坏的插入情况下,它最终会比AVL糟糕或更糟

对问题编辑的回应

我将提供了解AVL树的个人路径

首先,你必须了解什么是树旋转,所以忽略所有你听过的AVL算法,并理解这一点。直接进入你的大脑,这是一个右旋转,这是一个左旋转,以及每一个对树的作用,否则,精确方法的描述只会让你困惑

接下来,要了解平衡AVL树的诀窍是每个节点在其中记录其左右子树的高度差。“高度平衡”的定义是,对于树中的每个节点,该值介于-1和1之间(包括1)

接下来,请理解,如果您添加或删除了一个节点,则可能会导致树不平衡。但是,您只能更改添加或删除的节点的祖先节点的平衡。所以,你要做的是沿着你的路径回到树上,使用旋转来平衡你发现的任何不平衡的节点,并更新它们的平衡分数,直到树再次平衡

理解它的最后一部分是在适当的参考中查找用于重新平衡您找到的每个节点的特定旋转:这是它的“技术”,而不是高级概念。您只需在修改AVL树代码时或在数据结构检查期间记住细节。自从我上一次在调试器中打开AVL树代码以来已经有好几年了——实现往往会到达一个工作点,然后继续工作。所以我真的不记得了。你可以用一些扑克筹码在桌子上算出来,但很难确定你真的得到了所有的筹码(筹码不多)。最好只是查一下

然后是将其全部翻译成代码的业务


我认为除了最后一个阶段,查看代码清单对任何阶段都没有多大帮助,所以请忽略它们。即使在最好的情况下,代码写得很清楚,它看起来也像是教科书上对过程的描述,但没有图表。在更典型的情况下,这是一个混乱的C结构操作。所以只要坚持书本上的内容。

我同意,一个完整的计划是不合适的


虽然经典的AVL和RB树使用确定性方法,但我建议您看看“”这两种方法,它们保持平衡的成本较低,并且无论键的统计分布如何,都能保证良好的平衡。

AVL树效率低下,因为每次插入/删除都可能需要进行多次旋转

红黑树可能是更好的选择,因为插入/删除效率更高。这种结构保证到叶子的最长路径不超过最短路径的两倍。因此,虽然不如AVL树平衡,但可以避免最坏的不平衡情况


如果您的树将被多次读取,并且在创建后不会被更改,那么对于一个完全平衡的AVL树来说,额外的开销可能是值得的。此外,红黑树还需要为每个节点增加一个额外的存储位,这为节点提供了“颜色”。

我最近一直在使用AVL树进行一些工作

我能找到的关于如何平衡它们的最好帮助是通过搜索谷歌

我只是围绕这个伪代码编写了代码(如果您了解如何进行旋转,那么实现起来非常容易)


为了平衡AVL树,我刚刚编写了一系列函数,我想与这里的每个人共享。我想这个实现是完美的。当然欢迎提出疑问/问题/批评:

作为Stackoverflow的新手,我尝试在这里发布代码,但遇到了糟糕的格式问题。所以,在上面的链接上传了这个文件


干杯。

有一个自平衡avl树的完整实现@。它还实现对数时间连接和拆分操作以及映射/多重映射集合

是否希望树完全平衡?最常见的算法保证树在某种程度上是平衡的。例如,红黑树保证最深叶节点的深度不超过最浅叶节点深度的两倍。那么,您是在寻找一种算法来获取一棵树并对其进行平衡,还是一种算法作为树操作的一部分进行平衡,如插入、删除等。当然,必须定义“完美”算法。然而,在二叉树的上下文中,唯一有意义的定义是具有对数高度的二叉树,不是吗
IF tree is right heavy
{
  IF tree's right subtree is left heavy
  {
     Perform Double Left rotation 
  }
  ELSE
  {
     Perform Single Left rotation
  }
}
ELSE IF tree is left heavy
{
  IF tree's left subtree is right heavy
  {
     Perform Double Right rotation
  }
  ELSE
  {
     Perform Single Right rotation
  }
}