Shellsort是一个有趣的排序算法,我刚才遇到过。最令人惊讶的是,不同的间隙序列可以显着提高算法的速度。我做了一些阅读(不是很广泛),似乎Tokuda的序列被推荐用于实际应用。
另一个有趣的部分是比率2.20~2.25的顺序往往更有效。所以我做了一个小搜索,考虑了从2.20到2.50的比率序列,并尝试搜索哪个比率可以表现平均好。我发现这个比例:2.48在许多不同的试验中看起来平均表现良好。
然后,我想出了序列生成器:2.48 k-1 (让我们称之为248序列)并试图将它与Tokuda的序列进行比较。事实证明,它们的平均速度相等。 248个序列倾向于使用稍多的比较。
我知道我可能错了,这就是为什么我来这里寻求更有经验的程序员的更多意见。如果你没有得到问题,这是我的问题:
248 Sequence: ROUNDUP ( 2.48(k-1) ) eg: 1, 3, 7, 16, 38, 94, 233, 577, 1431, 3549, 8801, 21826, ... Tokuda's Sequence ROUNDUP ( (9k - 4k) / (5 * 4k - 1) ) eg: 1, 4, 9, 20, 46, 103, 233, 525, 1182, 2660, 5985, 13467, ...
由于@woolstar建议我也测试边缘情况,例如反转和排序。正如预期的那样,248序列在边缘情况下更快,因为248序列间隙更大,因此它更快地移动逆。
Shellsort实施
public static int compare = 0;
public static int swap = 0;
public static bool greaterthan(int a, int b) {
compare++;
return a > b;
}
public static int shellsort(int[] a, int[] gaps) {
// For keeping track of number of swap and comparison
compare = 0;
swap = 0;
int temp, gap, i, j;
// Finding a gap that is smaller than the length of the array
int gap_index = gaps.Length - 1;
while (gaps[gap_index] > a.Length) gap_index--;
while (gap_index >= 0) {
// h-sorting
gap = gaps[gap_index];
for (i = gap; i < a.Length; i++) {
temp = a[i];
for(j = i; (j >= gap) && (greaterthan(a[j - gap], temp)); j -= gap) {
a[j] = a[j - gap];
}
// swapping
a[j] = temp;
swap++;
}
gap_index--;
}
return compare;
}
答案 0 :(得分:4)
根据this reserach:(Ciura,Marcin(2001)“Shellsort平均案例的最佳增量”。在Freiwalds,Rusins。第13届计算理论基础国际研讨会论文集。伦敦:Springer-Verlag。pp.106-117)对于大小小于10 8 元素的数组,shell排序的主导操作应该是比较操作,而不是交换:
Knuth的讨论假设运行时间可近似为9×移动次数, 而图3和图4显示,对于每个序列,关键比较的数量是比运动次数更好的运行时间测量。对于N≤10 8 ,每次移动9个周期的渐近比率不太精确,并且,如果某个假设序列使得Θ(NlogN)移动,则永远不会达到。其他计算机体系结构的类比图将得出相同的结论。
当主导行动导致错误的结论时,对待行动 关于最佳序列。
在这种情况下,你的问题的答案是否定的:248序列更糟糕,因为它使用了更多的比较。你也可以考虑将你的序列与本文中提到的Ciura序列进行比较,因为这项研究似乎证明它比Tokuda的序列更好。