【问题标题】:How to deal with duplicates in red-black trees?如何处理红黑树中的重复项?
【发布时间】:2016-07-05 04:29:31
【问题描述】:

所以我一直(到目前为止没有成功)试图让我的红黑树实现与重复项一致地工作,但它似乎总是缺少那个小东西,所以我在这里。

我尝试让树向一侧倾斜,但它似乎没有正确平衡它(从颜色的角度来看)。我想问应该如何将重复添加到红黑树? (除了显然使节点变胖,持有或指向重复的键值)。

不是真的在寻找代码审查,而是对建议更感兴趣。所以基本上我用于插入和平衡的方法(取自Introduction to Algorithms,第三版)是这些(虽然旋转非常明显):

【问题讨论】:

  • 选择显而易见的,并为每个键保存一个值列表。键是唯一的。无论如何,您将如何查找节点?
  • 我会选择不为键的每个值添加单独的节点,而是将它们捆绑在单个节点中(在列表中或某处)。 R-B 树并不是真正为支持重复的数据结构设计的,而是为集合设计的。
  • 如果您告诉我们您认为缺少什么,您可以获得更好的答案。一个例子会产生奇迹。
  • @Sorin 想要一个更笼统的答案,因为正如下面评论中提到的,我只使用外部存储器,所以看代码会很痛苦。

标签: algorithm binary-tree red-black-tree


【解决方案1】:

如果您查看您在此处编写的伪代码,它对于键是否重复的问题是完全不可知的。这里的代码只看比较键的结果,并不关心它们是否相同。事实上,唯一键实现需要不遗余力地让RB-Insert 检测重复键。数据结构自然不关心这个,算法和证明持有是否存在重复键。如果您正确实现了这些功能,它应该可以正常工作。

我也不同意 cmets 建议您保持所谓的“胖节点”。例如,持有多个键是 C++ 的std::multimap 的常见实现。并不是说从计算复杂度的角度来看,你总共有 n 个键,但每个 k 都是一个倍数。使用“高效”的胖节点版本,基本查找操作的复杂度将是 Θ(log(n / k)) = Θ(log(n) - log(k));使用多键版本,复杂度将是 Θ(log(n))。在现实生活中,可能是 k ,这意味着相对差异可以忽略不计。

【讨论】:

  • 感谢您的建议,看来我有什么问题。我有一项繁琐的任务,即只使用外部内存(无法将树加载到内存中),所以这让我很烦。另外,伪代码不是右倾的吗,因为 insert 中的 else 语句将始终捕获 equals 情况?
  • 树会暂时向右倾斜,但调用RB-Insert-Fixup 会使它再次平衡。这样想:如果插入键 1, 2, 3, 4, ... (其中没有两个相同),树会变得不平衡吗?每个键最初将沿树的最右侧脊椎插入。在进行了足够多的修复后,它不一定会停留在那里。
  • 啊,明白了,这很可能是我的精益不起作用的原因,谢谢你的帮助,不胜感激。
猜你喜欢
  • 1970-01-01
  • 2021-03-20
  • 2012-02-04
  • 2010-09-06
  • 2013-06-05
  • 2018-02-07
  • 1970-01-01
  • 2018-11-07
  • 2015-11-17
相关资源
最近更新 更多