【发布时间】:2017-02-15 17:49:54
【问题描述】:
GCC 对 qsort 的实现使用 3 的中值来选择枢轴。在此过程中,这 3 个元素使用排序网络进行排序。
3 个元素的排序网络通常需要 3 次比较。但是在这个特定的实现中,可以跳过最后一个比较,具体取决于之前的比较:
if(a[0] > a[1]) swap(a[0], a[1]);
if(a[1] > a[2]) swap(a[1], a[2]);
else goto jump;
if(a[0] > a[1]) swap(a[0], a[1]);
jump:;
对于具有n = 4...16 的网络(具有已知的最小最佳比较次数的网络)可以做类似的事情吗?如果是这样,它们会是什么样子?它们会是什么样子?
更新: 到目前为止,我发现了另一个允许跳过一个比较的网络:
// sorting network for 5 elements
if (a[0] > a[1]) { SWAP(a[0], a[1]); }
if (a[2] > a[3]) { SWAP(a[2], a[3]); }
if (a[1] > a[3]) { SWAP(a[1], a[3]); }
if (a[2] > a[4]) { SWAP(a[2], a[4]); }
if (a[0] > a[2]) { SWAP(a[0], a[2]); }
if (a[1] > a[4]) { SWAP(a[1], a[4]); }
if (a[1] > a[2]) { SWAP(a[1], a[2]); }
if (a[3] > a[4]) { SWAP(a[3], a[4]); }
else { goto jump; }
if (a[2] > a[3]) { SWAP(a[2], a[3]); }
jump:;
我用 12345 的所有排列对此进行了测试,它对所有排列进行了正确排序。
【问题讨论】:
-
当您进行条件比较时,如果没有发生交换,那么最终比较将是多余的。您可能可以通过使用第二个原始索引数组并将该数组与数据交换,以及一个大小为 (n^2 - n) / 2 的数组用于可能的比较次数来跟踪哪些元素已经被比较元素(n 个东西,一次取 2 个),初始化为零并为每次比较设置为 1。