Data structures 何时选择RB树、B树或AVL树? 作为程序员,我应该考虑使用RB树、B-树还是AVL树? 在决定选择之前,需要考虑哪些关键点

Data structures 何时选择RB树、B树或AVL树? 作为程序员,我应该考虑使用RB树、B-树还是AVL树? 在决定选择之前,需要考虑哪些关键点,data-structures,tree,b-tree,avl-tree,red-black-tree,Data Structures,Tree,B Tree,Avl Tree,Red Black Tree,有人能解释一下每种树结构的场景吗?为什么在关键点上选择它而不是其他树结构 当您管理数千个以上的项目,并从磁盘或某个慢速存储介质对其进行分页时,会出现B树 在树上执行相当频繁的插入、删除和检索时,使用RB树 AVL树,当您的插入和删除相对于您的检索不频繁时。当选择数据结构时,您正在权衡以下因素: 检索速度与更新速度之比 该结构如何处理最坏情况下的操作,例如插入按排序顺序到达的记录 浪费的空间 我将首先阅读罗伯特·哈维引用的维基百科文章 实际上,当使用Java等语言工作时,一般程序员倾向于使用提

有人能解释一下每种树结构的场景吗?为什么在关键点上选择它而不是其他树结构

当您管理数千个以上的项目,并从磁盘或某个慢速存储介质对其进行分页时,会出现B树

在树上执行相当频繁的插入、删除和检索时,使用RB树


AVL树,当您的插入和删除相对于您的检索不频繁时。

当选择数据结构时,您正在权衡以下因素:

  • 检索速度与更新速度之比
  • 该结构如何处理最坏情况下的操作,例如插入按排序顺序到达的记录
  • 浪费的空间
我将首先阅读罗伯特·哈维引用的维基百科文章


实际上,当使用Java等语言工作时,一般程序员倾向于使用提供的集合类。如果在性能调优活动中发现集合性能有问题,则可以寻求替代实现。很少有企业主导的发展必须考虑的第一件事。很少有人需要手工实现这样的数据结构,通常有一些库可以使用。

我认为B+树是一种很好的通用有序容器数据结构,即使在主内存中也是如此。即使虚拟内存不是问题,缓存友好性通常也是问题,B+树特别适合顺序访问——与链表具有相同的渐近性能,但缓存友好性接近于简单数组。所有这些和O(logn)搜索、插入和删除

不过,B+树确实存在问题,例如,当您执行插入/删除操作时,项目在节点内移动,导致指向这些项目的指针无效。我有一个容器库,可以进行“游标维护”——游标将自己附加到链接列表中当前引用的叶节点上,因此可以自动修复或使其失效。因为很少有一个或两个以上的游标,所以它工作得很好——但仍然需要额外的工作

另一件事是B+树本质上就是这样。我想您可以根据是否需要剥离或重新创建非叶节点,但使用二叉树节点可以获得更大的灵活性。二叉树可以转换为链表并返回,而无需复制节点——您只需更改指针,然后记住,您现在将其视为不同的数据结构。除此之外,这意味着您可以很容易地合并树-将两棵树转换为列表,合并它们,然后再转换回一棵树

还有一件事是内存分配和释放。在二叉树中,这可以从算法中分离出来——用户可以创建一个节点,然后调用插入算法,删除可以提取节点(从树中分离节点,但不要释放内存)。在B-树或B+树中,这显然不起作用-数据将位于多项目节点中。编写insert方法“计划”操作而不修改节点,直到它们知道需要多少新节点并且可以分配这些节点为止,这是一项挑战

红黑对AVL?我不确定这有什么大区别。我自己的库有一个基于策略的“工具”类来操作节点,其中包含用于双链接列表、简单二叉树、散点树、红黑树和treap的方法,包括各种转换。其中一些方法只是因为我在某个时候感到无聊才被实现的。我不确定我是否测试过treap方法。我之所以选择红黑树而不是AVL,是因为我个人更了解算法——这并不意味着它们更简单,只是历史的巧合,我对它们更熟悉


最后一件事——我最初开发的B+树容器只是一个实验。这是一个从未真正结束的实验,但我不会鼓励其他人重复。如果你需要的是一个有序的容器,最好的答案是使用你现有的库提供的一个——例如,C++中的STD::MAP等。我的库经过多年的发展,花了相当长的时间才稳定下来,而我最近才发现它在技术上是不可移植的(依赖于一些未定义的行为WRT offsetof)。

当项目数超过32000时,内存中的B-Tree具有优势。。。从下面看

作为一个例子,我很欣赏这个问题——目前呈现的是fastutil IntAVLTreeSet与IntrTreeSet的选择。只需补充一些细节:B树可以有可变数量的子树,允许它保存许多记录,但仍然保持一个短高度树。RB-Tree在重新平衡方面没有那么严格的规则,这使得插入/删除比AVL-Tree更快。相反,AVL树更严格的平衡,所以查找比RB树更快。RB树在重新平衡上也具有更好的性能O(1),这使得它们更适合于具有回滚和滚动转发的持久数据结构。公平地说,OP问<代码>什么时候我应该考虑使用< /代码>,不是<代码>什么时候我应该考虑执行< /代码>。虽然最后一段是正确的,但在这个问题的背景下,它没有提供多少价值。即使使用库,您也需要了解算法,以便有效地选择最适合您业务需要的结构。