我必须对大量100000的双打进行排序。
关键是我不想对整个数组进行排序,而只是按降序查找最大的20000个元素。
目前我正在使用选择排序。有什么方法可以提高性能吗?
答案 0 :(得分:6)
在大多数现代设备上,100,000不是一个非常大的阵列。您确定不能使用标准库排序功能对所有这些进行排序吗?
您可以使用heapsort的变体来避免完整排序。通常在堆中,您构建整个数据集的堆(在您的情况下为100,000个元素)。相反,只允许堆增长到20,000个元素。将最大元素保留在堆顶部。堆已满(20,000个元素)后,将数据集的每个后续元素与堆顶部进行比较。如果下一个数据集元素大于堆的顶部,则跳过它。如果它小于堆的顶部,则弹出堆的顶部并从数据集中插入元素。
一旦完成了整个数据集,就会拥有数据集中20,000个最小元素的堆。您可以将它们逐个弹出到一个数组中,以获得一个已排序的数组。
此算法在O(N log K)时间内运行,其中N是数据集的大小(在您的示例中为100,000),K是您要保留的元素数(在您的示例中为20,000)。
答案 1 :(得分:3)
您可以通过使用Quick sort algorithm来提高效率,或者您可以在nlog(n)时间内使用合并排序。计算两个运行时间并找到适合你的snario的内容。
答案 2 :(得分:1)
如果使用bubble sort算法并向左移动较小的数字,则在第20.000次迭代后,数组末尾的数字将按降序排列。
1次迭代:7 3 5 2 4 8 1
2次迭代:7 5 3 4 8 2 1
3次迭代:7 5 4 8 3 2 1
第3次迭代后,最后有3个最小的元素按降序排列 我建议这样做,因为在这种情况下,复杂性取决于您要排序的元素数量。如果你想获得少量元素,你的程序将会快速运行。复杂度为O(k * n),其中k是您想要获得的元素数。
答案 3 :(得分:1)
我建议从bucket sort开始,然后使用一些更简单的算法对每个桶进行排序。如果它们中的任何一个仍然太大,您可以再次使用桶排序或另一个nlog(n)方法(例如mergesort或quicksort)。否则,选择(或更好,插入)就可以了。
仅供比较:selection / insertion / quicksort是O(n * n),mergesort是O(nlog(n)),bucket sort是O(n * k),其中k是桶的数量。选择k< log(n),你将获得比替代品更好的性能。
注意:quicksort的最坏情况是O(n * n),但实际上它要快得多。
更新 O(n * k)是铲斗排序的平均性能,而不是最差的情况,因此上述相同的说明适用。
答案 4 :(得分:1)
您可以使用修改后的快速排序获取前K个排序元素。关键是要意识到,一旦你按照枢轴重新排序列表,如果你的轴是≥K,你可以忘记对右侧进行排序。
简而言之,只需用
替换quicksort()
的“右手”递归调用即可
if (pivot >= k) quicksort(...)
或者,您可以遵循标准heapsort算法,但在从堆中提取K个元素后停止。
这两种方法都需要O(N + KlogN)时间,O(N)空间,并且可以就地完成。