1:实质上,希尔排序是对插入排序算法的一种改进,希尔算法虽然不是最快算法(运行时间是次二次方(比如: )),但是代码简单;(由于代码简单,对中等数据量的输入,希尔排序时首选的算法)
2,基本思想:避免了大量数据的移动,通过先比较相距较的元素排序;依据:对于一个h(k)有序的数组,在h(k-1)排序之后,仍然保证h(k)有序;
3:排序过程如下所示:对数组(81,94,11,96,12,35,17,95,28,58,41,75,15)
初始值 | 81 | 94 | 11 | 96 | 12 | 35 | 17 | 95 | 28 | 58 | 41 | 75 | 75 |
5-排序 | 35 | 17 | 11 | 28 | 12 | 41 | 75 | 15 | 96 | 58 | 81 | 94 | 95 |
3-排序 | 28 | 12 | 11 | 35 | 15 | 41 | 58 | 17 | 94 | 75 | 81 | 96 | 95 |
1-排序 | 11 | 12 | 15 | 17 | 28 | 35 | 41 | 58 | 75 | 81 | 94 | 95 | 96 |
分析:5-排序(gap=4):相同的元素表示相互比较数;
在3-排序,比如:28,35,58,75,95为一组,12,15,17,81为一组,11,41,94,96为一组,组内部相互比较
最后以增量1相互比较;
4:稳定性:
排序前一个序列中,如果出现N个与关键字相同的数据,那么排序后仍然按照原先序列的排列顺序排列,就说这个算法是稳定的,反之就是不稳定的。通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。
希尔排序稳定性分析:
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。
备注:希尔建议,gap从N/2开始,并且一直减半,直到最后gap等于1为止,此时程序终止;(实践中,不取2取2.2,但是没有理论依据哈)
代码如下:
public static <AnyType extends Comparable<? super AnyType>> void shellsort(AnyType[] a){
for(int gap = (int)(a.length/2.2);gap > 0;gap =(gap==2?1:(int)(gap/2.2))){
for(int i=gap;i<a.length;i++){
int j = i;
AnyType temp = a[j];
for(;j>=gap && a[j].compareTo(a[j-gap])<0;j=j-gap){
a[j] = a[j-gap];
a[j-gap] = temp;
}
}
}
}