思想:
1.确定一个增长量h,按照h作为数据分组的依据,对数组进行分组; 2.对分好组的每一组数据完成插入排序; 3.减小增长量,直到为1,重复第二步操作
public class Shell {
/*
对数组a中元素进行排序
*/
public static void sort(Comparable[] a){
//1.根据数组a的长度,确定增长量h的初始值,规则如下
int h = 1;
while (h < a.length/2){
h = 2*h+1;
}
//2.希尔排序
while (h >= 1){
//排序
//索引h处是第一个待插入的元素
for(int i = h;i < a.length; i++){//读到最后一个元素
//将带插入的元素插入到有序数列中,每个单独数列间隔为h
for(int j = i; j >= h; j -= h){
//待插入元素时a[j],比较与a[j-h]的大小
if(greater(a[j-h],a[j])){
exch(a,j-h,j);
}else{//待插入元素找到合适位置,结束循环
break;
}
}
}
//减小h的值,规则如下
h = h/2;
}
}
/*
比较v元素是否大于w元素
*/
private static boolean greater(Comparable v, Comparable w){//实现了compare接口的类均可使用
return v.compareTo(w) > 0;
}
/*
数组元素i和j交换位置
*/
private static void exch(Comparable[] a,int i,int j){
Comparable temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
测试代码:
import java.util.Arrays;
public class ShellTest {
public static void main(String[] args) {
Integer[] arr = {4,6,7,3,1,8,9,5,2};
Shell.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
输出结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
注意:
数组要使用基本类型的引用型,包装了comparable接口的类型的数组均可比较。
当进行数据量较大的排序时,希尔排序将展示出强大的时间优势,因为具体的时间复杂度算法较困难,可以用事后比较法使用具体数据来测试,会发现希尔排序相比插入排序等简单排序,时间耗时不在一个量级上。