1. 程式人生 > 實用技巧 >05_排序演算法之希爾排序

05_排序演算法之希爾排序

1.4 希爾排序

1.4.1 演算法原理

  1. 選定一個增長量h, 按照增長量h作為資料分組的依據, 對資料進行分組
  2. 對分好組的每一組資料完成插入排序
  3. 減小增長量, 最小減為1, 重複第二步操作

1.4.2 API設計

類名 Shell
構造方法 Shell();建立物件
成員方法 public static void (Comparable[] a); 陣列元素排序
private static boolean greater(Comparable v, Comparable w);判斷大小
private static void exch(Comparable[] a, int i, int j) 交換陣列a中索引為i和j處的值

1.4.3 演算法實現

package a_sort.d_shell;

/**
 * 希爾排序
 */
public class Shell {

    /**
     * 對陣列a中的元素進行排序
     *
     * @param a 需要排序的陣列
     */
    public static void sort(Comparable[] a) {
        int h = 1;//根據陣列a的長度, 確定增量h的初始值
        while (h < a.length / 2) {
            h = 2 * h + 1;
        }
        while (h >= 1) {
            //排序
            //找到待插入的元素
            for (int i = h; i < a.length; i++) {
                //把待插入的元素插入到有序數列中
                for (int j = i; j >= h; j -= h) {
                    //待插入的元素a[j], 比較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
     *
     * @param v 元素v
     * @param w 元素w
     * @return v大於w則返回true, 否則為false
     */
    private static boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) > 0;
    }

    /**
     * 元素交換
     *
     * @param a 陣列
     * @param i 陣列中的元素索引
     * @param j 陣列中的元素索引
     */
    private static void exch(Comparable[] a, int i, int j) {
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

1.4.4 演算法測試

package a_sort.d_shell;

import a_sort.b_selection.Selection;

import java.util.Arrays;

/**
 * 希爾排序測試類
 */
public class ShellTest {
    public static void main(String[] args) {
        Integer[] arr = {9, 1, 2, 5, 7, 4, 8, 6, 3, 5};
        Shell.sort(arr);

        System.out.println(Arrays.toString(arr));
    }
}

1.4.5 複雜度分析

教程未給出明確量級, 與插入排序對比 大致為插入演算法的1/1000, 所以是比較快速 的排序演算法.