1. 程式人生 > >演算法導論之插入排序

演算法導論之插入排序

排序問題

輸入: n個數的一個序列< A1,A2 , … , An >。
輸出: 序列的一個排列< A1’ , A2’ , … , An’ >, 滿足A1’ <= A2’ <= … <= An’ , 或者 A1’>= A2’ >= … >= An’ 。

插入排序

1. 原理簡述

使用插入排序來排序手中的撲克牌

  • 在未排序的數中取出一個數(從亂糟糟的牌堆裡拿出一張牌)
  • 將它插入到已經排好序的子集的正確位置中(將它插入手中已經排好順序的牌中,得到新的排好順序的牌)
  • 再取出一個數,將它插入到正確位置(再從亂糟糟的牌堆裡拿出一張牌)
  • 依次類推,直到序列裡所有的數都插入到正確的位置。

2. 虛擬碼

INSERTION_SORT(A)

    for j = 2 to A.length 
        key = A[j]
        //insert A[j] into the sorted sequence A[0...j-1]
        i = j-1
        while i > 0 and A[i] > key
          A[i+1] = A[i]
          i = i-1
        A[i+1] = key

3. 理解虛擬碼

  • 假設陣列下標從1 開始,陣列總共有n個數。
  • 排序方式是 升序排序
  • 對於序列中的第2至最後一個數,我們從取出第j個數(j 從 2 到 n),將其儲存在一個 key 臨時變數中,這樣,第j個位置就‘空’了出來
  • 對於A[0…j-1], 最開始時是[ A1 ], 只有一個數,所以它必定是排好序的。
  • 從第 j-1 到 第1 個數,依次和 key 比較,如果大於key ,那就把它搬到右邊的位置。
  • 當不再有 大於key 的數時,空出來的位置剛好是最適合key的,將key 插進去,便得到一個新的排好順序的序列。
  • 迴圈執行以上步驟,直到將第n 個數插入到正確的位置。

  • 對於 A[5,2,4,6,1,3] 的排序,過程如下圖所示

這裡寫圖片描述

4. C語言實現

整型數的插入排序,輸出結果可選擇升序或降序

  1. 標頭檔案, sort.h
    #ifndef __SORT_H__
    #define __SORT_H__
    void Insert_Sort_Integer(int array[], int length, unsigned char isAscending);
    #endif 
  1. C 檔案, sort.c
    #include "sort.h"

    /*  插入排序  */
    void Insert_Sort_Integer(int array[], int length, unsigned char isAscending)
    {
        int i, j;
        int temp;
        for (i = 1;i < length; i++)
        {
            temp = *(array + i);
            j = i - 1;
            if(isAscending)
            {
                while (j >= 0 && *(array + j) > temp)
                {
                    array[j + 1] = array[j];
                    j--;
                }
            }
            else 
            {
                while (j >= 0 && *(array + j) < temp)
                {
                    array[j + 1] = array[j];
                    j--;
                }
            }
            *(array + j + 1) = temp;
        }
    }

結語

插入排序屬於原址排序,但它的時間複雜度是O(n^2),和氣泡排序同樣的時間複雜度,效率比較低,使用較少, 後面將介紹 歸併排序,堆排序,快速排序