我有两种不同排序的实现,InsertionSort和ShellSort。
他们如下:
插入排序:
for (int pos = 0; pos < arrayToBeSorted.length; pos++) {
for (int secondMarker = pos; secondMarker > 0; secondMarker--) {
int currentValue = arrayToBeSorted[secondMarker];
int valueBeingCheckedAgainst = arrayToBeSorted[secondMarker - 1];
if (currentValue > valueBeingCheckedAgainst) {
break;
}
arrayToBeSorted[secondMarker] = arrayToBeSorted[secondMarker - 1];
arrayToBeSorted[secondMarker - 1] = currentValue;
}
}
希尔排序:
for (int gap = a.length / a.length; gap > 0; gap = (gap / 2)) {
for (int i = gap; i < a.length; i++) {
int tmp = a[i];
int j = i;
for (; j >= gap && tmp < (a[j - gap]); j -= gap) {
a[j] = a[j - gap];
}
a[j] = tmp;
}
}
我还有10个整数数组,它们包含32000个整数。我在这些类中调用静态sortArray方法之前得到的时间。结果如下:
对于InsertionSort.sortArray:
Solving array with: 32000 elements.
Time in milliseconds:264
Time in milliseconds:271
Time in milliseconds:268
Time in milliseconds:263
Time in milliseconds:259
Time in milliseconds:257
Time in milliseconds:258
Time in milliseconds:260
Time in milliseconds:259
Time in milliseconds:261
对于ShellSort:
Solving array with: 32000 elements.
Time in milliseconds:357
Time in milliseconds:337
Time in milliseconds:167
Time in milliseconds:168
Time in milliseconds:165
Time in milliseconds:168
Time in milliseconds:167
Time in milliseconds:167
Time in milliseconds:166
Time in milliseconds:167
那么他们之间有多大差异呢?它们基本上是相同的算法?
另外,ShellSort的前两次运行可能需要更长的时间,但其余的更快?
这是128000个元素的结果,再次插入InsertionSort:
Solving array with: 128000 elements.
Time in milliseconds:4292
Time in milliseconds:4267
Time in milliseconds:4241
Time in milliseconds:4252
Time in milliseconds:4253
Time in milliseconds:4248
Time in milliseconds:4261
Time in milliseconds:4260
Time in milliseconds:4333
Time in milliseconds:4261
希尔排序:
Solving array with: 128000 elements.
Time in milliseconds:5358
Time in milliseconds:5335
Time in milliseconds:2676
Time in milliseconds:2656
Time in milliseconds:2662
Time in milliseconds:2654
Time in milliseconds:2661
Time in milliseconds:2656
Time in milliseconds:2660
Time in milliseconds:2673
我确信我传递给方法的数组是完全相同的,而且它们是随机的。
答案 0 :(得分:1)
在插入排序中,您会变得更复杂,
for (int pos = 0; pos < arrayToBeSorted.length; pos++) {
for (int secondMarker = pos; secondMarker > 0; secondMarker--) {
int currentValue = arrayToBeSorted[secondMarker];
int valueBeingCheckedAgainst = arrayToBeSorted[secondMarker - 1];
if (currentValue > valueBeingCheckedAgainst) {
break;
}
arrayToBeSorted[secondMarker] = arrayToBeSorted[secondMarker - 1];
arrayToBeSorted[secondMarker - 1] = currentValue;
}
}
您从内部循环中读取数组中的值,并且前一个位置的值不小,您可以向数组写入两个值。
在shell排序中,
for (int i = gap; i < a.length; i++) {
int tmp = a[i];
int j = i;
for (; j >= gap && tmp < (a[j - gap]); j -= gap) {
a[j] = a[j - gap];
}
a[j] = tmp;
}
你读取了一次的值,在内部循环之外,并且在内部循环体中只有一次写入,在内部循环之后只写一次值。
这样效率更高,因此shell排序更快是可以理解的。两个第一个shell排序较慢可能是因为包装
for (int gap = a.length / a.length; gap > 0; gap = (gap / 2)) {
将JIT混淆了一段时间后才注意到gap
可以替换为1并且包络循环被消除。