1. 程式人生 > >決勝經典演算法之插入排序

決勝經典演算法之插入排序

習題答案

題目回顧

在上一篇文章中,我們以數列從小到大排列為例,講了選擇排序。結尾處的思考題如下:

如果要實現從大到小排列,上述程式碼該做如何修改呢?

同樣,要解答這個問題也很簡單,下面放上答案。

答案

我們知道,從小到大排序時,選擇排序就是選出最小的數,並將其放在最開始的位置。同理,從大到小排序時,只需要選出最大的數,將其放在最開始的位置就可以了。參考如下程式碼:

public static void selectSort(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        int min = i;
        for (int j = i; j < arr.length; j++) {
            if (arr[j] > arr[min]) {
                min = j;
            }
        }
        
        if (min != i) {
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
}

怎麼樣,你答對了嗎?


本篇文章的內容是講第三種排序方法——插入排序。
還是之前的問題:

問題挑戰

現有如下數字:   
3,44,38,5,47,15,36,26,27,2,46,4,19,50,48   
一共15個數字,請將其從小到大依次排列。

演算法解析

所謂“插入排序”,重點在“插入”。具體說來,就是評估數列裡面的每一個元素。這種評估依次進行,數列中,如果它前面的數值比它小(從小到大排序時),則把它放在比它小的數值後,直到最後一個元素評估完成。
整個過程理解起來並不難,結合下面的動圖演示將會更加清晰直接。

詳細步驟

下面讓我們來分步驟拆解整個插入排序:

  1. 從第一個元素開始,該元素可以認為已經被排序;
  2. 取出下一個元素,在已經排序的元素序列中從後向前掃描;
  3. 如果該元素(已排序)大於新元素,將該元素移到下一位置;
  4. 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
  5. 將新元素插入到該位置後;重複步驟2~5,直到最後一個元素完成。

整個流程如下圖所示:

虛擬碼

接下來,我們使用虛擬碼實現上述過程

InsertSort (input ele[],input length)
for i <-- 1 to n-1
    for j <-- i-1 to 0
    if a[i] > a[j] break
if j!=i-1
temp <-- a[i]
for k <-- i to j+2
    a[k] <-- a[k-1]
a[j+1] <-- temp
end

Java程式碼實現

接下來,我們使用Java程式語言實現上述演算法。

public static void insertSort(int[] arr) {
    int temp;
    int j;
    for (int i = 1; i < arr.length; i++) {
        for (j = i - 1; j >= 0; j--) {
            if (arr[i] > arr[j])
            break;
        }
        if (j != i - 1) {
            temp = arr[i];
            for (int k = i; k > j + 1; k--) {
                arr[k] = arr[k - 1];
            }
            arr[j + 1] = temp;
        }
    }
}

思考題

1. 如果要實現從大到小排列,上述程式碼該做如何修改呢?

思考題答案依舊會在下篇連載中公佈,大家加油哦!