希尔排序

希尔排序是插入排序的优化算法,时间复杂度为O(nlogn),也称为增量缩小的算法.

希尔排序使用了一个序列h1,h2,h3...hk,称为增量序列,只要h1=1 任何增量序列都是可行的,不过有些增量序列可能会比另外一些增量序列更好一点.

在使用增量hk排序以后,对每个i,都有a[i]<=a[i+k],即相隔k个的元素都已经排序,此时称文件是hk排序的.
对希尔排序来说一个重要的性质就是,一个hk排序的文件,保持他的hk有序性,即使用下一个增量(hk-1)排序后,之前基于hk的排序依然是有效的.

举例说明
数组a = [4,2,1,9,3,5,8,6,7]
通常我们选取的增量序列是 hk= length/2(向下取整) hk-1 = hk/2(向下取整) ... h1 =1(更好的增量序列,暂时不讨论)

那么对a来说我们选取的增量序列就是 4,2,1

原数组a = [4,2,1,9,3,5,8,6,7]
第一轮,增量序列为4
a[4]=3,a[0]=4,{4,3}3插入排序(改变)
a=[3,2,1,9,4,5,8,6,7]

a[5]=5,a[1]=2,{2,5}5插入排序(不变)
a=[3,2,1,9,4,5,8,6,7]

a[6]=8,a[2]=1,{1,8}8插入排序(不变)
a=[3,2,1,9,4,5,8,6,7]

a[7]=6,a[3]=9,{9,6}6插入排序(改变)
a=[3,2,1,6,4,5,8,9,7]

a[8]=7,a[4]=4,{4,7}7插入排序(不变)
a=[3,2,1,6,4,5,8,9,7]

第一轮结束.a=[3,2,1,6,4,5,8,9,7]

第二轮排序,增量序列为2
a[2]=1,a[0]=3,{3,1}1插入排序(改变)
a=[1,2,3,6,4,5,8,9,7]

a[3]=6,a[1]=2,{2,6}6插入排序(不变)
a=[1,2,3,6,4,5,8,9,7]

a[4]=4,a[2]=3,a[0]=1,{1,3,4}4插入排序(不变)
a=[1,2,3,6,4,5,8,9,7]

a[5]=5,a[3]=6,a[1]=2,{2,6,5}5插入排序(改变)
a=[1,2,3,5,4,6,8,9,7]

a[6]=8,a[4]=4,a[2]=3,a[0]=1,{1,3,4,8}8插入排序(不变)
a=[1,2,3,5,4,6,8,9,7]

a[7]=9,a[5]=6,a[3]=5,a[1]=2,{2,5,6,9}9插入排序(不变)
a=[1,2,3,5,4,6,8,9,7]

a[8]=7,a[6]=8,a[4]=4,a[2]=3,a[0]=1,{1,3,4,8,7}7插入排序(改变)
a=[1,2,3,5,4,6,7,9,8]

第二轮排序结束.a=[1,2,3,5,4,6,7,9,8]

第三轮排序开始,增量为1

a[1]=2,a[0]=1,{1,2}2插入排序(不变)
a=[1,2,3,5,4,6,7,9,8]

a[2]=3,a[1]=2,a[0]=1,{1,2,3}3插入排序(不变)
a=[1,2,3,5,4,6,7,9,8]

a[3]=5,a[2]=3,a[1]=2,a[0]=1,{1,2,3,5}5插入排序(不变)
a=[1,2,3,5,4,6,7,9,8]

a[4]=4,a[3]=5,a[2]=3,a[1]=2,a[0]=1,{1,2,3,5,4}4插入排序(改变)
a=[1,2,3,4,5,6,7,9,8]

a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6}6插入排序(不变)
a=[1,2,3,4,5,6,7,9,8]

a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7}7插入排序(不变)
a=[1,2,3,4,5,6,7,9,8]

a[7]=9,a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7,9}9插入排序(不变)
a=[1,2,3,4,5,6,7,9,8]

a[8]=8,a[7]=9,a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7,9,8}8插入排序(改变)
a=[1,2,3,4,5,6,7,8,9]

第三轮排序完毕,整体排序完毕
数组a=[1,2,3,4,5,6,7,8,9]

     

 1     public static <T extends Comparable<? super T>> void shell(T[] arr) {
 2         int length = arr.length;
 3         for (int step = length / 2; step > 0; step /= 2) {
 4             for (int i = step; i < length; i++) {
 5                 int j = 0;
 6                 T tmp = arr[i];
 7                 for (j = i; j >= step && tmp.compareTo(arr[j - step]) < 0; j -= step) {
 8                     arr[j] = arr[j - step];
 9                 }
10                 arr[j] = tmp;
11             }
12 
13         }
14     }
View Code

 

posted @ 2015-11-01 01:52  coldridgeValley  阅读(842)  评论(0编辑  收藏  举报