一、 介紹
插入排序,一般也被稱為直接插入排序。對於少量元素的排序,它是一個有效的演算法 [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 協議》,轉載必須註明作者和本文連結