【发布时间】:2012-06-19 02:20:56
【问题描述】:
我正在对整数键数组进行排序。
数据信息:
- 数组长度为 1176 个元素
- 密钥在 750 000 和 135 000 000 之间; 0也是可能的
- 有很多重复项,在每个数组中只有 48 到 100 个不同的键,但无法预测哪些值会超出整个范围
- 有很多长排序子序列,大多数数组由 33 到 80 个排序子序列组成
- 最小元素为0; 0 的数量是可预测的,并且在非常窄的范围内,每个数组大约 150 个
到目前为止我尝试了什么:
-
stdlib.h qsort;
这很慢,现在我的函数在每次执行排序上花费 0.6 秒,而 stdlib.h qsort 是 1.0 秒;这与 std::sort 具有相同的性能
-
Timsort;
我试过这个:https://github.com/swenson/sort 和这个:http://code.google.com/p/timsort/source/browse/trunk/timSort.c?spec=svn17&r=17;两者都明显慢于 stdlib qsort
-
他们对快速排序和插入排序的组合是迄今为止我的数据最快的;我尝试了各种设置并将枢轴作为中间元素(不是 3 的中值)并从 28 个元素子数组(默认不是 8 个)开始插入排序提供了最佳性能
-
shell排序;
简单的实现与本文的差距:http://en.wikipedia.org/wiki/Shellsort;它很不错,虽然比 stdlib qsort 慢
我的想法是 qsort 做了很多交换和破坏(即反向)排序的子序列,所以应该有一些方法可以通过利用数据结构来改进它,不幸的是到目前为止我所有的尝试都失败了。
如果你好奇这是什么类型的数据,那是在已经在前一个棋盘上排序的各种棋盘上评估的扑克手组(这是排序子序列的来源)。
函数在 C 中。我使用 Visual Studio 2010。 有什么想法吗?
样本数据:http://pastebin.com/kKUdnU3N
完整执行示例(1176 种):https://dl.dropbox.com/u/86311885/out.zip
【问题讨论】:
-
你能发个样本吗?对于这样的问题,如果我们可以直接进行基准测试会有所帮助。
-
示例发布; >>基数排序为此,我需要 135 000 000 个元素数组并对其进行迭代:) 如果我可以设计一些智能快速哈希,那么也许...顺便说一句,如果您想进行更多基准测试,我可以发布示例数据集(1k 排序) :)
-
@PiotrLopusiewicz:你会使用 C++ 吗? C++ STL 中的 map 可以快速解决这个问题。或者您可以编写平衡树作为集合使用。
-
@nhahtdh STL Map 与大多数特定问题的算法相比效率不高,主要是因为它频繁的分配和移动。 (计时看看。)
-
@Crashworks:您可能是对的,因为输入大小很小(1000 范围)。在具有大量重复键的较大输入上,它应该比排序算法更快。