1. 程式人生 > >選擇排序,插入排序以及希爾排序

選擇排序,插入排序以及希爾排序

[] stat 元素交換 sta .com urn ins ret 間隔

1. 選擇排序

  1. 首先,找到數組中最小的那個元素;
  2. 將它與數組中的第一個元素交換位置;
  3. 在剩下的數組中找到最小的元素,和數組的第二個元素交換位置,如此循環往復;
public class Selection{

    // 將數組a按升序排列
    public static void sort(Comparable[] a){
        int N = a.length;
        for(int i = 0; i < N; i++){
            int min = i;
            for(int j = i + 1; j < N; j++){
                if(less(a[j], a[min])){
                    min = j;
                }
                exch(a, i, min);
            }
        }
    }

    // 數組兩個元素比較
    private static boolean less(Comparable v, Comparable w){
        return v.compareTo(w) < 0;
    }

    // 交換數組的兩個元素
    private static void exch(Comparable[] a, int i, int j){
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

    // 測試數組是否有序
    public static boolean isSorted(Comparable[] a){
        for(int i = 1; i < a.length; i++){
            if(less(a[i], a[i - 1])){
                return false;
            }
        }
        return true;
    }
}

2. 插入排序

  • 當前索引左邊的所有元素都是有序的;
  • 更小的元素插入之前,需要將比它的元素右移一位;
public class Insertion{
    public static void sort(Comparable[] a){
        int N = a.length;
        for(int i = 1; i < N; i++){
            // 將 a[i] 插入到 a[i-1], a[i-2], a[i-3]... 之中
            for(int j = i; j > 0 && less(a[j], a[j - 1]); j--){
                exch(a, j, j-1);
            }
        }
    }
}

3. 希爾排序

  • 基於插入排序;
  • 插入排序只會交換相鄰元素;希爾排序交換不相鄰元素,以及對數組局部排序;
  • 希爾排序的思想是使數組中任意間隔為h的元素都是有序的;
public class Shell(){
    public static void sort(Comparable[] a){
        int N = a.length;
        int h = 1;
        while(h < N/3){
            h = 3 * h + 1;
        }
        while(h >= 1){
            // 將數組變為h有序
            for(int i = h; i < N; i++){
                for(int j = i; j >= h && less(a[j], a[j - h]); j -= h){
                    exch(a, j, j-h);
                }
            }
            h = h/3;
        }
    }
}

參考資料:

  • 算法(紅皮書)

選擇排序,插入排序以及希爾排序