希尔排序的思想是是使数组中任意间隔为h的元素都是有序的
关于h的值的取法:在程序中依次取13 4 1
while(h<n/3)
h=3*h+1;//给h取值1 4 13 40
希尔排序效率分析:
当刚开始时h比较大,各个子数组都比较短,而排完一次序之后的h值虽然减小导致子数组变大,但是由于前面的排序,子数组是部分有序的,对于这两种情况,插入排序都很适合。
public class test1
{
public void sort(int [] a)
{
int n=a.length;
int h=1;//h是间隔
System.out.print("初始数组:");
for (int k=0;k<n;k++)
System.out.print(a[k]+" ");
System.out.println();
while(h<n/3)
h=3*h+1;//给h取值1 4 13 40
//System.out.println("h="+h);
while(h>=1) {
for (int i = h; i < n; i++) {
int j = i;
int times=0;
while (j >= h && a[j] < a[j - h]) {
int temp = a[j];
a[j] = a[j - h];
a[j - h] = temp;
times++;
}
System.out.print("i="+i+"第" + times + "趟排序的结果,h="+h+": ");
for (int k = 0; k < n; k++)
System.out.print(a[k] + " ");
System.out.println();
}
h = h / 3;//改变间隔 h由...->40->13->4>1
System.out.println();
}
}
public static void main(String args [])
{
test1 t=new test1();
int array[]={16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
t.sort(array);
}
}
从运行结果中可以看成,当h比较大时,外层循环额次数比较少。“0趟”表示a[i]和a[i-h]的顺序符号,不用交换
单纯的插入排序运行结果,h=1一个值
从运行结果可以发现,当只有h=1一个值也就是插入排序时,交换的次数增加了很多,在采用希尔排序时,由于之前的h=13和4的两次排序使得子数组已经部分有序,所以即使后来h=1退化成插入排序,交换的次数也比较少。