我有一组双精度数据,我需要总是对它们的列表进行排序。在添加数据时对数据进行排序的最佳算法是什么?
最好我的意思是数据计数中的Big-O最少,数据计数中的Small-O(最差情况),以及所需空间中的最小Small-O,如果可能的话,按顺序排列。
设置大小实际上是可变的,从少量(30)到大量数据(+ 10M)。
答案 0 :(得分:28)
构建像red-black tree或AVL tree这样的自平衡二叉树将允许Θ(lg n)插入和移除,以及按排序顺序检索所有元素的Θ(n)深度优先遍历),具有Θ(n)内存使用。实现有点复杂,但它们很有效,并且大多数语言都有库实现,因此在大多数情况下它们是首选。
此外,可以通过使用其下方的节点总数来注释树中的每个边(或等效地,节点)来完成对第i个元素的检索。然后可以在Θ(lg n)时间和Θ(1)空间中找到第i个元素,例如:
node *find_index(node *root, int i) {
while (node) {
if (i == root->left_count)
return root;
else if (i < root->left_count)
root = root->left;
else {
i -= root->left_count + 1;
root = root->right;
}
}
return NULL; // i > number of nodes
}
支持这一点的实现可以在debian的libavl中找到;遗憾的是,维护者的网站似乎已关闭,但可以从debian's servers检索。
答案 1 :(得分:4)
used for indexes of database programs的结构是B +树。它是一种平衡的n-ary树。
对于具有h级索引的b阶B +树:
我在我的程序中使用它。您可以将数据添加到结构中,并始终按顺序,从前到后或从后到前遍历,或快速搜索任何值。如果找不到该值,则可以使用插入点添加值。
您可以通过使用b(桶的大小)来优化程序的结构。
关于B +树的有趣演示:Tree-Structured Indexes
你可以get the entire code in C++。
编辑:现在我看到你的评论,你需要知道“集合中的第i个排序元素”是一个重要的。突然间,这使得许多数据结构不够理想。
最好使用SortedList,甚至更好的SortedDictionary。请参阅文章:Squeezing more performance from SortedList。两个结构都有一个GetKey函数,它将返回第i个元素。
答案 2 :(得分:2)
可能heap sort.堆只有O(log N)才能添加新数据,您可以在O(N log N)时间内随时弹出净结果。
如果你总是需要每次排序整个列表,那么除了insertion sort.之外没有其他选项可能很多O(N ^ 2)虽然你可以制作linked skip lists的巨大麻烦它O(N log N)。
答案 3 :(得分:2)
我会使用堆/优先级队列。最坏的情况与运行时的平均情况相同。下一个元素可以在O(log n)时间内找到。
我从Here is a templatized C# implementation派生的答案 4 :(得分:2)
好的,您希望对数据进行排序,但需要通过索引号提取数据。
从一棵基本的树开始,比如上面提到的红黑树。
修改树算法,以便在插入和删除过程中遇到的所有节点向树中插入元素时,保留每个分支下元素数的计数。
然后,当您从树中提取数据时,您可以随时计算索引,并根据是否大于或小于您要提取的索引来了解要采用的分支。
另一个考虑因素。使用动态内存分配的树中的10M元素+会吸收大量内存开销。即,指针可能占用比实际数据更多的空间,以及用于实现数据结构的其他任何成员。这将导致严重的内存碎片,并且在最坏的情况下会降低系统的整体性能。 (从虚拟内存中来回转换数据。)您可能需要考虑实现块和动态内存分配的组合。在某种情况下,您将树排序为数据块,从而减少内存开销。
答案 5 :(得分:2)
如果您只需要知道评论中所述的第i个最小元素,请使用以作者姓氏命名的BFPRT算法:Blum,Floyd,Pratt,Rivest和Tarjan,并且通常同意是同一篇论文中最重要的大型计算机科学大脑。 O(n)最坏情况。
答案 6 :(得分:1)
查看维基百科中的comparison排序算法。
答案 7 :(得分:1)
Randomized Jumplists也很有趣。 它们需要更少的空间作为BST和跳过列表。 插入和删除是O(log n)
答案 8 :(得分:0)
通过“一组双数据”,你的意思是一组实值数字吗?其中一个比较常用的算法是heap sort,我会检查出来。它的大部分操作都是O(n * log(n)),这是非常好的,但不符合你的所有标准。 heapsort的优点在于,您自己编写代码相当简单,而且许多语言都提供了管理已排序堆的库。