平衡二叉树 (AVL)

发布于 2024-07-05 08:18:42 字数 122 浏览 12 评论 0原文

好吧,这对周围的 CS 人员来说是理论领域的又一题。

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

你们能帮我解决这个问题吗?

Ok, this is another one in the theory realm for the CS guys around.

In the 90's I did fairly well in implementing BST's. The only thing I could never get my head around was the intricacy of the algorithm to balance a Binary Tree (AVL).

Can you guys help me on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我不咬妳我踢妳 2024-07-12 08:18:43

替罪羊树可能具有最容易理解的平衡确定算法。 如果任何插入导致新节点太深,它会通过查看重量平衡而不是高度平衡来找到要重新平衡的节点。 删除时是否重新平衡的规则也很简单。 它不在节点中存储任何神秘信息。 证明它是正确的比较棘手,但你不需要它来理解算法......

但是,与 AVL 不同的是,它并不总是高度平衡的。 与红黑一样,它的不平衡是有限的,但与红黑不同的是,它可以通过参数进行调整,因此对于大多数实际用途,它看起来就像您需要的那样平衡。 不过,我怀疑如果你把它调整得太紧,对于最坏情况的插入来说,它最终会和 AVL 一样糟糕,甚至更糟。

对问题编辑的回应

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

首先,您必须了解什么是树旋转,因此请忽略您听说过 AVL 算法的所有其他内容并理解它。 弄清楚哪个是右旋转,哪个是左旋转,以及每种旋转对树的作用,否则精确方法的描述只会让您感到困惑。

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

接下来,请了解如果添加或删除节点,则可能会使树不平衡。 但是您只能更改作为您添加或删除的节点的祖先的节点的平衡。 因此,您要做的就是恢复树,使用旋转来平衡您发现的任何不平衡节点,并更新它们的平衡分数,直到树再次平衡。

理解它的最后一部分是在一个像样的参考中查找用于重新平衡您找到的每个节点的特定旋转:这是它的“技术”,而不是高概念。 您只需要在修改 AVL 树代码时或者在数据结构考试期间记住细节即可。 距离我上次在调试器中打开 AVL 树代码已经有很多年了——实现往往会达到可以工作的程度,然后继续工作。 所以我真的不记得了。 您可以在桌子上使用一些扑克筹码来解决这个问题,但很难确定您是否真的掌握了所有情况(数量不多)。 最好只是查一下。

然后就是将其全部翻译成代码。

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

A scapegoat tree possibly has the simplest balance-determination algorithm to understand. If any insertion causes the new node to be too deep, it finds a node around which to rebalance, by looking at weight balance rather than height balance. The rule for whether to rebalance on delete is also simple. It doesn't store any arcane information in the nodes. It's trickier to prove that it's correct, but you don't need that to understand the algorithm...

However, unlike an AVL it isn't height-balanced at all times. Like red-black its unbalance is bounded, but unlike red-black it's tunable with a parameter, so for most practical purposes it looks as balanced as you need it to be. I suspect that if you tune it too tightly, though, it ends up as bad or worse than AVL for worst-case insertions.

Response to question edit

I'll provide my personal path to understanding AVL trees.

First you have to understand what a tree rotation is, so ignore everything else you've ever heard the AVL algorithms and understand that. Get straight in your head which is a right rotation and which is a left rotation, and what each does to the tree, or else the descriptions of the precise methods will just confuse you.

Next, understand that the trick for balancing AVL trees is that each node records in it the difference between the height of its left and right subtrees. The definition of 'height balanced' is that this is between -1 and 1 inclusive for every node in the tree.

Next, understand that if you have added or removed a node, you may have unbalanced the tree. But you can only have changed the balance of nodes which are ancestors of the node you added or removed. So, what you're going to do is work your way back up the tree, using rotations to balance any unbalanced nodes you find, and updating their balance score, until the tree is balanced again.

The final part of understanding it is to look up in a decent reference the specific rotations used to rebalance each node you find: this is the "technique" of it as opposed to the high concept. You only have to remember the details while modifying AVL tree code or maybe during data structures exams. It's years since I last had AVL tree code so much as open in the debugger - implementations tend to get to a point where they work and then stay working. So I really do not remember. You can sort of work it out on a table using a few poker chips, but it's hard to be sure you've really got all the cases (there aren't many). Best just to look it up.

Then there's the business of translating it all into code.

I don't think that looking at code listings helps very much with any stage except the last, so ignore them. Even in the best case, where the code is clearly written, it will look like a textbook description of the process, but without the diagrams. In a more typical case it's a mess of C struct manipulation. So just stick to the books.

飘过的浮云 2024-07-12 08:18:43

我最近一直在做一些 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
  }
}

I've been doing some work with AVL trees lately.

The best help I was able to find on how to balance them was through searching google.

I just coded around this pseudo code (if you understand how to do rotations it is pretty easy to implement).

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
  }
}
烟花易冷人易散 2024-07-12 08:18:43

我同意,完整的程序是不合适的。

虽然经典的 AVL 和 RB 树使用确定性方法,但我建议查看“随机二进制搜索树”保持平衡的成本较低,并且无论键的统计分布如何都能保证良好的平衡。

I agree, a complete program would not be appropriate.

While classical AVL and RB tree use a deterministic approach, I would suggest to have a look at "Randomized binary search trees" that are less costly to keep balanced and guarantee a good balancing regardless the statistical distribution of the keys.

久光 2024-07-12 08:18:43

AVL 树效率低下,因为每次插入/删除都必须进行多次旋转。

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

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

The AVL tree is inefficient because you have to do potentially many rotations per insertion/deletion.

The Red-Black tree is probably a better alternative because insertions/deletions are much more efficient. This structure guarantees the longest path to a leaf is no more than twice the shortest path. So while less balanced than an AVL tree, the worst unbalanced cases are avoided.

If your tree will be read many times, and won't be altered after it's created, it may be worth the extra overhead for a fully-balanced AVL tree. Also the Red-Black tree requires one extra bit of storage for each node, which give the node's "color".

贵在坚持 2024-07-12 08:18:43

为了平衡 AVL 树,我刚刚编写了一堆函数,我想在这里与大家分享。 我想这个实现是完美的。 当然欢迎质疑/问题/批评:

http://uploading.com/files/5883f1c7 /AVL_Balance.cpp/

作为 Stackoverflow 的新手,我尝试在这里发布我的代码,但遇到了错误的格式问题。 因此,将文件上传到上面的链接上。

干杯。

For balancing an AVL Tree I just wrote a bunch of functions which I thought of sharing with everyone here. I guess this implementation is flawless. Queries/questions/criticism are of course welcome:

http://uploading.com/files/5883f1c7/AVL_Balance.cpp/

Being a novice to Stackoverflow, I tried posting my code here but was stuck with bad formatting issues. So, uploaded the file on the above link.

Cheers.

野生奥特曼 2024-07-12 08:18:43

自平衡 avl 树的完整实现 @ http://code.google .com/p/self-balancing-avl-tree/ 。 它还实现对数时间连接和分割操作以及映射/多重映射集合

there's a complete implementation of a self balancing avl tree @ http://code.google.com/p/self-balancing-avl-tree/ . it also implements logarithmic time concatenate and split operations as well as a map/multimap collections

久光 2024-07-12 08:18:42

我认为在这里发布节点平衡算法的完整代码并不好,因为它们变得相当大。 然而,关于 红黑树 的维基百科文章包含该算法的完整 C 实现,并且关于 AVL 树 的文章也有几个高质量实现的链接。

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

I don't think it's good to post complete codes for node balancing algorithms here since they get quite big. However, the Wikipedia article on red-black trees contains a complete C implementation of the algorithm and the article on AVL trees has several links to high-quality implementations as well.

These two implementations are enough for most general-purpose scenarios.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文