排序算法.md

初級排序算法


  1. 遊戲規則
    1. 關注對象是重新排列數組元素的算法。
    2. 大多數情況只會兩種方法操作數據:less()exch().
    3. 排序成本模型:需要計算比較和交換的數量。對不交換的算法,會計算訪問數組的次數。
    4. 自定義的數據類型,只需要實現一個compareTo() 方法來定義目標類型對象的自然序列。通常對於> < = ,返回值用(-1 0 +1)。
  2. 排序分類

這裏寫圖片描述

選擇排序

  1. 簡單選擇排序
    1. 每次選出剩餘最小的元素,並與剩餘未交換的第一位進行交換。
    2. 交換總次數N。時間效率取決於比較次數。n方/2次比較,n次交換。
public class Selection{
    public statice void sort(String[] a){
        int len = a.length;
        for (int i = 0; i < len-1; i++){
            int min = i;
            int temp;
            for (int j = i+1; j < len; j++){
                if ( a[j] < a[min]){
                    min =j;
               }
               temp = a[min]; a[min] = a[i]; a[i] = a[min];
           }
       }
   }
}
  1. 堆排序
    1. 時間複雜度爲O(nlogn),空間複雜度爲O(1)
    2. 堆排序借用數據結構,二叉堆。
      二叉堆的性質:父節點的鍵值總是>=子節點鍵值;每個節點都是一個一個二叉堆。
    3. 經常用在 大數Top K問題上。
public class HeapSort{
    private int[] arr;

    public void HeapSort(int[] arr){
        this.arr = arr;       
    }
    /*堆有序第一步
    *數據化堆
    */
    for (int i = arr.length/2; i > 0; i--){
        heapAdjust(arr, i, arr.length);
    }

    /*堆有序第二步
    *堆排序
    */
    for(int i = arr.length - 1; i > 0; i--){
        swap(arr, 0, i);
        heapAdjust(arr, 0, i);
    }

    /* 構建堆的過程 
     * @param arr 需要排序的數組 
     * @param i 需要構建堆的根節點的序號 
     * @param n 數組的長度 
     */ 
     private static void heapAdjust(int[] arr, int i, int n){
         while (2*i+1 < n){
             int j = 2*i+1;
             if (j < n && (arr[j] < arr[j+1]))
                 j++;
             if (!(arr[j] < arr[k]))
                 break;
             exch(arr, k, j);
             k = j;
         }
         private static int exch(int[] arr, int i, int n){
             int t = arr[i];
             arr[i] = arr[n];
             arr[n] = t;
         }
     }

}

插入排序

  1. 直接插入排序
    1. 將其餘所有元素插入到之前的元素中。
    2. 當前索引左邊的都是有序數列。
    3. 插入排序所需時間,取決於當前的初始順序,因此對非隨機數組更有效。
public void InsertSort(int[] arr){

    for (int i = 1; i < arr.length; i++){
        if (a[i] < a[i-1]){
            int j = i-1;
            int x = a[i];
            a[i] = a[i-1];
            while(x < a[j]){
                a[j+1] = a[j];
                j--;
            }
            a[j] = x;
        }
    }
}
  1. 希爾排序
    1. 基於插入排序,快速算法。
    2. 交換不相鄰的元素,以對數組局部最優;然後用插入排序對局部最優排序。
    3. 任意間隔h的元素都是有序。
public void shellSort(int[] arr, int n){
    int dk = n/2;
    while(dk >= 1){
        ShellInsertSort(arr, n, dk);
        dk = dk/2;
    }

    private void ShellInsertSort(int[] arr, int n, int dk){
        for (int i = dk; i < n; i++){
            if (a[i] < a[i-dk]){
                int j = i-dk;
                int x = a[i]
                while(x < a[j]){
                    a[j+dk] = a[j];
                    j -= dk;
                }
                a[j] = x;
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章