用于两端排序列表的最佳数据结构

时间:2010-05-15 06:18:29

标签: python performance algorithm data-structures collections

我需要一个可以执行以下操作的集合数据结构:

  • 排序
  • 允许我从列表O(log n)的前面快速弹出值
  • 插入新值后保留排序
  • 允许用户指定的比较功能,因为我将存储元组并希望对特定值进行排序
  • 不需要线程安全
  • 可选择允许有效的haskey()查找(我很乐意为此维护一个单独的哈希表)

我在这个阶段的想法是我需要一个优先级队列一个哈希表,虽然我不知道我是否可以快速弹出值两个结束优先队列。另一种可能性就是维护OrderedDictionary,并在每次向其添加更多数据时进行插入排序。

因为我对中等数量项目的性能感兴趣(我估计会少于200,000),我不确定这些操作需要什么渐近性能。 n不会无限增长,因此k中的低常数性能k * O(n)可能同样重要O(n)。也就是说,我希望插入和弹出操作都花费O(log n)时间。

此外,Python中是否有任何特定的实现?我真的很想避免自己编写这段代码。

7 个答案:

答案 0 :(得分:2)

使用blist或数据库(例如stdlib中的sqlite),您可能会在这些类型的操作中获得良好的性能。

答案 1 :(得分:1)

我建议使用某种平衡的二叉树,例如红黑树。

A search on PyPi引发了几个实现。在谷歌上搜索会给你更多。

PyPi上的

bintrees看起来非常完整,同时具有Python和C / Cython实现。我没有使用它,所以请注意。

红黑树保持排序,大多数操作(插入,删除,查找)都是O(log2(N)),因此在200,000个条目的树中查找元素将平均进行17-18次比较。 / p>

答案 2 :(得分:1)

听起来skip list会满足您的所有要求。它基本上是一个动态大小的排序链表,带有O(log n)插入和删除。

我真的不懂Python,但这个链接似乎很相关:

http://infohost.nmt.edu/tcc/help/lang/python/examples/pyskip/

答案 3 :(得分:1)

我认为你需要它排序,因为你按排序顺序访问元素?

您可以使用任何平衡二叉树的任何实现,每个节点上的附加信息告诉您该节点的后代数(通常称为Order Statistic Binary Tree)。

使用此结构,给定元素的等级(甚至最小/最大),您可以在O(log n)时间内访问/删除它。

这使得所有操作(按等级访问/插入/删除,弹出前/后,插入/删除/按值搜索)O(logn)时间,同时允许自定义排序方法。

此外,显然python有一个AVL树(第一个平衡树结构之一)实现,它支持订单统计:http://www.python.org/ftp/python/contrib-09-Dec-1999/DataStructures/avl.README

所以你不需要自定义实现。

答案 4 :(得分:1)

除了散列之外,你要找的是一个双端优先级队列,也就是优先级deque。

如果您对排序的需求不会超出管理数据的最小值和最大值,那么您要查看的另一个结构可能是间隔堆,其优点是O(1)查找最小值和最大值如果你需要查看值(虽然deleteMin和deleteMax仍然是O(log(N)))。不幸的是,我不知道Python中的任何实现,所以我认为你必须自己动手。

以下是算法教科书的附录,如果您感兴趣,可以描述区间堆:

http://www.mhhe.com/engcs/compsci/sahni/enrich/c9/interval.pdf

答案 5 :(得分:1)

如果你真的可以允许O(log n)进行pop,dequeue和insert,那么一个简单的平衡搜索树就像红黑树一样充足。

您可以通过维护指向树中最小和最大元素的直接指针来优化它,然后在(1)将元素插入树中或(2)弹出或出列时更新它,这当然会失效分别指针。但是因为树是平衡的,所以无论如何都会有一些洗牌,你可以更新corr。指针在同一时间。

还有一种叫做min-max heap的东西(参见Binpedia Heap的维基百科条目),它实现了一个“双端优先级队列”,即一个可以从前端和后端弹出的队列。但是,您无法按顺序访问整个对象列表,而搜索树可以在O(n)时间内有效地迭代。

最小 - 最大堆的好处是,当前 min和max对象可以在O(1)时间内读取,搜索树需要O(log(n))读取最小或最大对象,除非你有如上所述的缓存指针。

答案 6 :(得分:-1)

如果这是Java,我会使用带有NavigableSet接口的TreeSet。

这是以红黑树实现的。