【问题标题】:Data structure for fast insertion/deletion with sorting用于快速插入/删除排序的数据结构
【发布时间】:2011-07-09 15:04:47
【问题描述】:

我正在拼命寻找一种数据结构,它允许我执行大量插入、几乎一样多的删除(可能相同的数量级)和非常快速的最高(或最低)查找) 价值。 删除将始终只影响最高(或最低)值。 问题是必须对值进行排序,并且在任何时候我都可以在其他两个之间的任何点插入一个元素。我想在任何时候快速读取(和删除)的唯一值是最大值(或者,再次,最小值)。

有什么推荐的吗?

请对您提出的答案进行算法复杂性分析。

【问题讨论】:

  • 请澄清您的问题和cmets。当您似乎想要的只是插入时,您会说最大插入。此外,您说必须对值进行排序,但您还说您只需要读取最大值。最后,O(log n) 非常接近 O(1),但您似乎想要更快。您实际要执行多少操作?
  • 操作应该在每秒 200 万次修改左右徘徊。绝大多数将是最大插入,而相对较小的百分比(

标签: algorithm performance data-structures tree big-o


【解决方案1】:

看来您需要Max-Heap

支持 O(log n) 插入,O(1) 查找最大值和 O(log n) 删除最大值。

【讨论】:

  • +1 但理想情况下,我需要 O(1) 最大插入和删除,因为除了查找之外,它的执行可能比其他任何事情都多。
  • @emaster:“最大插入”是什么意思?你不是说插入吗?如果插入最大值,那么它将是堆中的 O(1)。如果你只是想插入,那么你可以用你的结构在线性时间内对 n 个数字进行排序。如果仅使用比较,则排序有 Omega(nlogn) 下限...
  • @emaster70:O(log n) 非常接近 O(1),尤其是在具有高分支因子的堆中。或者按照 Jim Mischel 的回答中的建议使用斐波那契堆。
【解决方案2】:

这个数据结构被称为self-balancing binary search tree,它在我使用的所有语言中都实现了,除了 Borland Pascal。
您提到的所有操作(添加/删除/查找)的成本是O(logn)。最小-最大查找也可以是O(1)

您可以在O(n)中按排序顺序遍历所有元素。

编辑
我不是建议堆,因为它不满足 “必须排序” 的要求。

如果您需要插入/删除/查找仅最大,那么我建议您使用排序数组或链表。最大插入/删除/查找O(1) 并且所有元素都已排序。

【讨论】:

  • +1 但与上面相同,O(log n) 似乎不足以进行最大插入和删除:(
  • O(1) 中的最小-最大查找?我认为你需要做一些调整..(在 AVL、RB-Tree 中,..)比如有一个指向 Min / Max 的节点,..
  • @emaster70 对于最大插入/删除,简单数组应该可以工作:)
  • @OscarMederos 好吧,存储指向最大值的指针不会影响复杂性。
【解决方案3】:

堆就是你想要的。这是二进制堆的简单实现。是最大堆还是最小堆取决于你传递给它的比较函数:http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=789

请注意,二叉堆并不是构建堆的唯一方法。但它可能是最容易构建的,并且在大多数情况下都表现良好。

堆中的项目没有排序,尽管它们是有序的。唯一的保证是最高(最低)的项目位于堆的顶部,并且将是您请求下一个项目时检索到的项目。

您正在构建的内容听起来像是priority queue。还有其他方法可以实现优先级队列。例如,我见过基于skip list 的优先级队列优于基于堆的优先级队列。

如果您确实需要 O(1) 插入,请查看 Fibonacci heap 之类的内容。

【讨论】:

  • 斐波那契堆是为从事 CS 理论的人准备的,以要求尽可能好的渐近运行时间。常量很糟糕——改用配对堆或其他东西。
  • 考虑到我的问题的性质,如果我能够开发出一个好的实现,要么是斐波那契堆,要么 - 正如 user635541 所建议的 - 配对堆应该像它们看起来一样接近鉴于我的操作类型的平均频率分布,我可以满足我的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 2011-04-07
  • 2014-03-04
  • 1970-01-01
  • 2018-11-16
  • 2010-10-27
  • 1970-01-01
相关资源
最近更新 更多