将流式数据读入排序列表

时间:2011-07-03 18:36:06

标签: algorithm performance sorting collections big-o

我们知道,一般来说,“智能”比较会对最差情况下的任意数据进行排序O(N * log(N))。

我的问题是如果我们被要求不对集合进行排序,而是对数据流进行排序会发生什么。也就是说,值一个接一个地给我们,没有下一步的指示(除了数据有效/在范围内)。直觉上,人们可能会认为它优于对数据进行排序(比如逐个拿起扑克牌),而不是收集所有数据并稍后排序(在发牌后对扑克牌进行排序)。实际情况如此吗?

收集和排序将是O(N + N * log(N))= O(N * log(N))。但是,如果我们对其进行排序,则为O(N * K),其中K =找到正确索引的时间+插入元素的时间。这使事情变得复杂,因为K的值现在取决于我们对数据结构的选择。数组在查找索引方面是优越的,但是浪费了插入元素的时间。链表可以更容易插入,但不能二进制搜索以查找索引。

是否有关于此问题的完整讨论?我们什么时候应该使用一种方法?可能会有一个理想的中间策略每隔一段时间排序一次吗?

4 个答案:

答案 0 :(得分:3)

Balanced tree sort具有O(N log N)的复杂性,并在添加元素时按排序顺序维护列表。

答案 1 :(得分:1)

绝对不是!

首先,如果我可以对流式数据进行排序,我可以接受O(N)中的所有数据,然后将其流式传输给自己并使用更快的方法对其进行排序。即您可以执行从所有数据到流的减少,这意味着它不能更快​​。

其次,您正在描述插入排序,它实际上在O(N^2)时间内运行(即您对O(NK)的描述是正确的,但K不是常数,而是一个函数N),因为可能需要O(N)时间才能找到合适的索引。您可以将其改进为二进制插入排序,但这将在O(NlogN)中运行(假设您正在使用链接列表,即使使用二进制优化,数组仍将采用O(N^2)),因此您没有真正保存任何东西。

可能还值得一提的是一般原则;只要你在比较模型中(即你没有关于你正在排序的数据的任何非平凡和有用的信息,这是一般情况),任何排序算法都将充其量{{1 }}。即此模型中排序算法的最差运行时间为O(NlogN)。这不是一个假设,而是一个定理。所以不可能更快找到任何东西(在相同的假设下)。

答案 2 :(得分:1)

好的,如果流的时间相对较慢,那么当你的最后一个元素到达时,你将有一个完全排序的列表(减去最后一个元素)。然后,剩下要做的就是单个二进制搜索循环, O(log n)不是完整的二进制排序, O(n log n)。潜在地,有一种感知的性能提升,因为你在其他排序算法上有了先机。

从流中管理,排队和提取数据是一个完全不同的问题,可能会对您的意图产生反作用。我不建议这样做,除非您可以在流式传输一个或两个元素的同一时间对整个数据集进行排序(并且您对编写流式传输部分感觉很好)。

答案 3 :(得分:0)

在树排序表现不佳的情况下使用堆排序,即大型数据集,因为树排序需要额外的空间来存储树结构。