排序演算法之「插入排序(Insertion Sort)」

ice_moss發表於2021-03-08

一、 介紹

插入排序,一般也被稱為直接插入排序。對於少量元素的排序,它是一個有效的演算法 [1] 。插入排序是一種最簡單的排序方法,它的基本思想是將一個記錄插入到已經排好序的有序表中,從而一個新的、記錄數增1的有序表。在其實現過程使用雙層迴圈,外層迴圈對除了第一個元素之外的所有元素,內層迴圈對當前元素前面有序表進行待插入位置查詢,並進行移動 。

中文名:插入排序

外文名: Insertion sort

別 稱: 直接插入排序

分 類: 排序方法

時間複雜度: O(N^(1-2))

空間複雜度: O(1)

穩定性: 穩定

二. 邏輯

在一組無序的陣列arr[]中,將索引為1的的元素arr[1]和索引為0的元素arr[0]進行比較,if( arr[1] < arr[0] )則將arr[1]和arr[0]的位置互換,如果arr[1]>arr[0], 則尋找索引為2的元素arr[2]和arr[1]進行比較,if(arr[2] < arr[1] ) 則將arr[1]和arr[2]的位置互換,再進一步將arr[2]和arr[0]比較,if(arr[2] < arr[0]) 則這兩個元素進行位置的互換;如果arr[2] > arr[1] 則尋找到下一個元素,以此類推……

例如:

​ 陣列{3, 5, 2, 1, 6, 4, 7}, 此時陣列是無序的

1.以索引為1的數開始 (陣列第二個元素,因為第一個數已經排序在了第一個位置)
arr[0] = 3, arr[1] = 5, arr[2] = 2, arr[3] = 1, arr[4] = 6, arr[5] = 4, arr[6] = 7
這裡 5 > 3,所以得到陣列仍然是{3, 5, 2, 1, 6, 4, 7}
2.再將索引加1,此時就是2和5比,因為2 < 5,所以得到陣列{3, 2, 5, 1, 6, 4, 7}
然後再將2和3進行比較,因為2 < 3, 所以得到陣列{2, 3, 5, 1, 6, 4, 7}
3.以此類推………就可以得到有序陣列{1, 2, 3, 4, 5, 6, 7}

三. 程式碼

這裡我使用的是用C++實現

#include<iostream>

using namespace std;

//使用模板函式
template <typename T>
void InsertionSort(T arr[], int n){
    //第一個元素已經排在第一個位置,這裡從索引為1開始
    for(int i = 1; i < n; i++){

        for(int j = i; j > 0; j--){
            if(arr[j] < arr[j-1])
                //swap來自c++標準庫
                swap(arr[j], arr[j-1]);
            else
                break;
        }
    }

}
//測試InsertionSort
int main(){
    int q[10] = {2, 4, 1, 2, 6, 4, 2, 1, 1, 6};
    //InsertionSort函式的呼叫
    InsertionSort(q, 10);
    for(int i = 0; i < 10; i++)
        cout<<q[i]<<endl;
    return 0;
}



輸出結果為:

1
1
1
2
2
2
4
4
6
6

上述使用的是傳統的模式,明視訊記憶體在一些問題,問題來自於swap函式,使用swap函式需要進行3次賦值操作,所以會降低插入排序的效率

下面我們進行最佳化我們的最佳化版本不使用swap函式,而是直接使用賦值操作

程式碼如下:

#include<iostream>

using namespace std;

//使用模板函式
template <typename T>
void InsertionSort(T arr[], int n){
    //第一個元素已經排在第一個位置,這裡從索引為1開始
    for(int i = 1; i < n; i++){
        //將arr[i]的值賦值給e
        int e = arr[i];
        int j; 
        // j儲存元素e應該插入的位置
        for (j = i; j > 0 && arr[j-1] > e; j--)
            arr[j] = arr[j-1];
        arr[j] = e;
    }
return;
}
//測試InsertionSort
int main(){
    int q[10] = {2, 4, 1, 2, 6, 4, 2, 1, 1, 6};
    //InsertionSort函式的呼叫
    InsertionSort(q, 10);
    for(int i = 0; i < 10; i++)
        cout<<q[i]<<endl;
    return 0;

}

輸出結果為:

1
1
1
2
2
2
4
4
6
6
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章