C++ 对于少量整数,最快的排序算法是什么?
我想知道最快的算法是什么。我有8个介于0和3000之间的整数,需要对它们进行排序。虽然只有8个整数,但此操作将执行数百万次。仅对8个整数执行,并且考虑到范围远大于8,插入排序可能是最好的。首先尝试一下,如果分析表明它不是瓶颈,那么就离开它C++ 对于少量整数,最快的排序算法是什么?,c++,sorting,C++,Sorting,我想知道最快的算法是什么。我有8个介于0和3000之间的整数,需要对它们进行排序。虽然只有8个整数,但此操作将执行数百万次。仅对8个整数执行,并且考虑到范围远大于8,插入排序可能是最好的。首先尝试一下,如果分析表明它不是瓶颈,那么就离开它 (取决于许多因素,快速排序优于插入排序的截止点通常在5到10项之间)。最快的方法是编写大量的if语句来比较它们,以确定它们的确切顺序。这将消除任何排序算法的开销。比较排序算法的一个好来源是。 请注意,即使是初始订单状态也会影响结果。但是无论如何,对于8个整数,
(取决于许多因素,快速排序优于插入排序的截止点通常在5到10项之间)。最快的方法是编写大量的
if
语句来比较它们,以确定它们的确切顺序。这将消除任何排序算法的开销。比较排序算法的一个好来源是。
请注意,即使是初始订单状态也会影响结果。但是无论如何,对于8个整数,即使是一个普通的冒泡排序也应该完成这项工作。最快的方法是在硬件中实现一个。除此之外,最快的方法只能通过测量来确定。我想试试
std::sort
- 鸽子洞(桶)分拣,重复使用桶
- 一组
语句,以及if
- 插入排序
另外,冒泡排序、选择排序和shell排序也值得注意。我从来没有真正实现过这些,因为它们的rep不好,但是你可以尝试一下。对于正整数,最快的排序称为abacus排序-它是O(n)
如果您只有很少的项,那么您不太可能注意到选择任何特定算法的性能差异。下面引用Bentley等人的话,设计排序函数可能会很有趣: 对插入排序的各种改进,包括二进制搜索、循环展开和将n=2作为特例处理,都没有帮助。最简单的代码是最快的 (我的重点。)
这表明,无需特别修改的简单插入排序确实是一个很好的起点。正如Peter所指出的,八项确实有点棘手,因为它正好位于插入排序和快速排序之间的界限范围内。对于非常小的整数,冒泡排序可以非常快。带有数值比较的冒泡排序可以以非常低的开销编写,对于较小的n,O(n logN)和O(n^2)之间的实际速度差会消失。这里是C99中奇偶合并排序网络的一个实现(很抱歉使用了“错误”的语言): 我在我的机器上按插入排序计时
void sort8_insertion(int *a)
{
for (int i = 1; i < 8; i++)
{
int tmp = a[i];
int j = i;
for (; j && tmp < a[j - 1]; --j)
a[j] = a[j - 1];
a[j] = tmp;
}
}
void sort8_插入(int*a)
{
对于(int i=1;i<8;i++)
{
int tmp=a[i];
int j=i;
对于(;j&&tmp
对于大约1000万次排序(正好是40320次可能排列的250倍),排序网络耗时0.39秒,而插入排序耗时0.88秒。在我看来这两个都足够快了。(图中显示生成排列的时间约为0.04秒。)您是否分析了代码以表明排序是一个瓶颈?如果这不是一个瓶颈,那么加快它不会给你带来太多好处。对八个短整数进行排序非常快
一般来说,std::sort()将比您能编写的任何东西都要快,除非您是真正的排序专家 我对{0429857128617142314325713000}的所有排列运行了一个排序算法库 最快的是:
name time stable in-place
AddressSort 0.537 No No
CenteredLinearInsertionSort 0.621 Yes No
CenteredBinaryInsertionSort 0.634 Yes No
BinaryInsertionSort 0.639 Yes Yes
...
QuickSort 0.650 No Yes
...
BubbleSort 0.802 Yes Yes
有关AddressSort的详细信息,请参见有关整数,您可以尝试基数排序。它是O(N)。年后)最多32个输入, 看。 对于8个输入,它给出19个交换,如Sven Marnach的回答:
o--^--^--------^--------------------------o
| | |
o--v--|--^--^--|--^--^--------------------o
| | | | | |
o--^--v--|--v--|--|--|--^--------^--------o
| | | | | | |
o--v-----v-----|--|--|--|--^--^--|--^--^--o
| | | | | | | | |
o--^--^--------v--|--v--|--|--|--v--|--v--o
| | | | | | |
o--v--|--^--^-----v-----|--|--|-----v-----o
| | | | | |
o--^--v--|--v-----------v--|--v-----------o
| | |
o--v-----v-----------------v--------------o
There are 19 comparators in this network,
grouped into 7 parallel operations.
[[0,1],[2,3],[4,5],[6,7]]
[[0,2],[1,3],[4,6],[5,7]]
[[1,2],[5,6],[0,4],[3,7]]
[[1,5],[2,6]]
[[1,4],[3,6]]
[[2,4],[3,5]]
[[3,4]]
这在很大程度上取决于值是什么以及它们的初始顺序(以及算法的具体实现、平台等)。最终你需要衡量和比较自己。最快的排序有多重要。由于数字如此之少,这几乎没有什么区别。因此,除非这对速度非常敏感,否则我将从排序8个元素的最简单方法开始。如果该操作将执行数百万次,可能需要做的一件事是并行运行多个排序8整数操作。N个核可以产生N倍的加速…事实上,想想看。。。获得最少IF数的“算法”是什么?这被称为排序网络,我相信最佳排序网络是已知的八个元素。这不一定比循环快。展开循环实际上会使代码变慢,这种情况并不少见。@Jörgen Sigvardsson:如果编写代码来显式表示已知的排序网络,这并不是维护的噩梦。它也很容易测试,因为您可以覆盖8!=40k个显著不同的输入(OK,加上一堆更多的相等值)。我想如果你开始编写一组完全特殊的条件句,那么(a)你会很快陷入麻烦,(b)你无论如何也不会想出任何接近最优的东西。@Jörgen Sigvardsson:他没有要求简短或可维护的代码,他问什么是最快的。如果你有SIMD,排序网络特别有效。@Paul R:我想是的。MMX等是否有成对比较指令?垂直比较(寄存器到寄存器),是。水平比较(寄存器内的比较高/低),否。只要您有一个合理数量的小整数集,这些整数集可以并行排序,那么SIMD就可以通过(垂直)最大/最小操作实现一个排序网络。典型的考试
o--^--^--------^--------------------------o
| | |
o--v--|--^--^--|--^--^--------------------o
| | | | | |
o--^--v--|--v--|--|--|--^--------^--------o
| | | | | | |
o--v-----v-----|--|--|--|--^--^--|--^--^--o
| | | | | | | | |
o--^--^--------v--|--v--|--|--|--v--|--v--o
| | | | | | |
o--v--|--^--^-----v-----|--|--|-----v-----o
| | | | | |
o--^--v--|--v-----------v--|--v-----------o
| | |
o--v-----v-----------------v--------------o
There are 19 comparators in this network,
grouped into 7 parallel operations.
[[0,1],[2,3],[4,5],[6,7]]
[[0,2],[1,3],[4,6],[5,7]]
[[1,2],[5,6],[0,4],[3,7]]
[[1,5],[2,6]]
[[1,4],[3,6]]
[[2,4],[3,5]]
[[3,4]]