1. 程式人生 > >排序演算法——希爾排序的圖解、程式碼實現以及時間複雜度分析

排序演算法——希爾排序的圖解、程式碼實現以及時間複雜度分析

希爾排序(Shellsort)

希爾排序是衝破二次時間屏障的第一批演算法之一。
希爾排序通過比較相距一定間隔的元素來工作;各躺比較所用的距離隨著演算法的進行而減小,直到只比較相鄰元素的最後一趟排序為止。由於這個原因,希爾排序有時也叫做縮減增量排序
希爾排序使用一個序列h1,h2,…,hi,這個序列叫做增量序列(increment sequence)。增量序列只要求h1=1,以及hi>hi-1。在使用hk的一趟排序之後,對於每一個i我們都有a[i] <= a[i+hk];所有間隔hk的元素都被排序。此時稱檔案是hk-sorted(hk排序的)。
希爾的增量序列
增量序列的一個流行(但是不好)的選擇是使用Shell建議的序列:ht

= (N/2)向下取整和hk = (hk+1/2)向下取整

希爾排序的原理以及程式設計實現

希爾排序的原理:

img2

下面是使用希爾序列的希爾排序的程式設計實現:

      /**
     * 希爾排序的實現例程。
     * 希爾排序以增量進行分組,每一組進行組內的插入排序,使得該組有序。
     * @param a 要排序的陣列
     * @param <AnyType> 陣列的型別
     * @return 已經有序的陣列
     */
    public static <AnyType extends Comparable<? super
AnyType>> AnyType[] shellSort(AnyType[] a){ int i; for (int gap=a.length/2;gap>0;gap/=2){ //增量序列 /* * 下面就是插入排序*/ for (int j=gap;j<a.length;j++) { //從當前增量序列處開始向後遍歷 AnyType tmp = a[j]; for (i = j; i>=gap && tmp.compareTo(a[i - gap]) < 0
; i -= gap) { a[i]=a[i-gap]; } a[i]=tmp; } } return a; }

希爾排序的最壞情形分析

希爾排序的執行時間依賴於增量序列的選擇。

7.3 使用希爾增量時希爾排序的最壞情形執行時間為θ(N2)。

Hibbard增量序列:1,4,7,…,2k-1。這個增量的特點是增量沒有公因子

7.4 使用Hibbard增量的希爾排序的最壞情形執行時間為θ(N3/2)。

Sedgewick提出了幾種增量序列,其最壞情形執行時間為O(N4/3)。其中最好的是序列{1,5,19,41,109,…},該序列中的項或者是9*4i-9*2i+1的形式,或者是4i-3*2i+1。這個增量序列在實踐中還是最為人們稱道的。
希爾排序的效能在事件中是完全可以接受的,即使是對於數以萬計的N仍是如此。程式設計的簡單特點使得它成為對適度地大量的輸入資料經常選用的演算法。