danwenxuan 2016-09-19
希尔排序:它通过比较相距一定间隔的元素来工作,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。希尔排序也叫缩减增量排序(diminishing increment sort)。
希尔排序使用一个序列h1,h2,h3,…,ht,叫做增量序列(increment sequence)。在使用增量hk的一趟排序之后,对于每一个i我们都有a[i] ≤ a[i+hk],所有相隔hk的元素都被排序,此时称文件是hk排序的(hk-sorted)。希尔排序的一个重要性质:一个hk排序的文件(然后将是hk-1排序的)保持它的hk排序性。
hk排序的一般做法是,对于hk,hk+1,...,N-1中的每一个位置i,把其上的元素放到i,i-hk,i-2hk,...中的正确位置上。一趟hk排序的作用就是对hk个独立的子数组执行一次插入排序。
Shell建议序列:ht=N/2值的下界,hk=hk+1/2值的下界。使用希尔增量的希尔排序:
/** * Shellsort,using Shell's(poor) increments * @param a an array of Comparable items */ public static <AnyType extends Comparable<? super AnyType>> void shellsort(AnyType[] a){ int j; for(int gap=a.length/2;gap>0;gap/=2){ for(int i=gap;i<a.length;i++){ AnyType tmp = a[i]; for(j=i;j>=gap&&tmp.compareTo(a[j-gap])<0;j-=gap){ a[j] = a[j-gap]; } a[j] = tmp; } } }
使用希尔增量时希尔排序的最坏情形运行时间为O(N2)。
Hibbard提出一个稍微不同的增量序列,它的增量形如1,3,7,...,2K-1。虽然这些增量几乎是相同的,但关键的区别是相邻的增量没有公因子。
使用Hibbard增量的希尔排序的最坏情形运行时间为O(N3/2)。
Sedgewick提出几种增量序列,其最坏情形运行时间(也是可以达到的)为O(N4/3)。其中最好的序列{1,5,19,41,109,...},该序列中的项或者是9*4i-9*2i+1形式,或者是4i-3*2i+1形式。
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。