我已经研究排序算法几个星期了,但我的一个问题仍然没有答案:对于固定大小的和随机访问的集合,是否有最佳的顺序比较排序?大多数排序算法都适应于集合的大小,但是知道要排序的集合的大小可以为这个大小选择特定的排序算法。例如,下面的算法应该用最优比较数和最佳交换或赋值数(它是C++,但应该很容易翻译成任何语言)对三个值进行排序:
void sort3(int& x, int& y, int& z)
{
if (x < y) {
if (z < y) {
if (z < x) {
int tmp = z;
z = y;
y = x;
x = tmp;
} else {
std::swap(y, z);
}
}
} else if (z < y) {
std::swap(x, z);
} else if (z < x) {
int tmp = x;
x = y;
y = z;
z = tmp;
} else {
std::swap(x, y);
}
}不管输入法是什么,这个算法将对三个值进行排序,最多有3个比较和4个赋值。我可能是错的,但我不认为排序三个值可以做到比这个算法更少的比较和更少的分配。如果确实如此,那么这将是对三个值进行排序的最佳比较排序算法。
由于某些排列算法,似乎可以产生任意大小的这种最优排序算法,但我找不到这样的生成算法,而且编写这样的算法似乎也不简单。我试图找到一些固定大小的近似最优排序算法,但是找不到任何简单的方法来生成这样的算法:
这是一个很好的介绍,但我的问题基本上如下:对于固定大小的集合,是否有已知的方法来生成顺序比较排序算法,这些算法对于赋值的数量和/或所执行的比较数来说是最优的?
发布于 2015-10-05 20:21:16
寻找最优算法的问题是“最优”这个词:排序算法在一种情况下可能是最优的,但至少在另一种情况下是次优的。问题是,你设计它的最佳目的是什么。以你的算法为例。这是最优的序列:
x < y <= z
x >= y > z(旁白:这意味着您未能正确地优化x == y <= z和x >= y == z的情况,因为它们本来可以由相同的代码路径处理。但这不是我的重点。)
然而,对于其他四种可能的订单,您的算法是次优的。现在,您可以编写像您这样的算法,这些算法对于六种可能的排序中的任意两种都是最优的(进行两种比较),但是在其他四种情况下,它们都需要第三种比较。
对于任何输入顺序,都不可能编写最优的算法。对于大于2的对象的计数,这是正确的。也就是说,您必须决定要优化哪些输入顺序,以及是否有您不想优化的输入顺序。
为了进一步理解我的观点:考虑一下快速排序和插入排序这两种算法。你能说一个绝对比另一个好吗?不,你不能。对于随机输入,快速排序会快得多,但它只是被插入排序的输入典当。只有当您知道需要什么样的输入数据时,您才能选择一个而不是另一个。
这有点像试图测量量子粒子的位置和动量。如果你知道一个,你就不知道另一个,反之亦然。你可以同时测量两者,但是两者都是不精确的。大自然根本不允许你同时精确地知道这两者。同样,当您首先在算法中比较x和y时,您已经打破了手头问题的对称性,使得对三分之二可能的输入序列进行最优排序是不可能的。
https://softwareengineering.stackexchange.com/questions/299059
复制相似问题