一、什麼是插入排序算法
它的工做原理是經過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。數組
從第二個元素開始r[1],那麼將他左邊的元素做爲一個已經有序的序列,將r[1]按從小到大的順序插入到函數
有序序列中的合適位置使之成爲一個新的有序序列;接着將r[2]插入到左邊的有序序列中,使之成爲一個spa
新的有序序列,依次類推,直道將全部的元素都遍歷完了以後,那麼整個數組就是一個從小到大的有序數組了。3d
二、效果演示指針
這是須要進行排序的序列code
對於第1個元素8來講,它自己就是有序的blog
再來考慮第2個元素6,由於他比8小,交換一次位置排序
再來考慮第3個元素2,由於他比8小,交換一次位置class
2又比左邊的6小,交換一次位置
再來考慮第4個元素,由於他比8小,交換一次位置
3又比左邊的6小,交換一次位置
3比左邊的2大,不需交換,前4個元素就已經排序完畢,後面的依次類推
二、時間複雜度
O(n^2)
三、算法實現(基於C++)
1 /* 直接插入排序算法實現 */ 2 template<typename T> 3 void insertSort(T a[], int count) 4 { 5 /* 找到a[i]這個元素的合適插入位置,由於第一個元素前面沒有元素,沒法進行比較,因此從第二個元素開始 */ 6 for (int i = 1; i < count; i++) { 7 for (int j = i; j > 0 && a[j - 1] > a[j]; j--) { 8 std::swap(a[j-1], a[j]); 9 } 10 } 11 }
四、直接插入算法的改進
從上面的算法實現上可知,咱們的直接插入排序算法上須要進行大量的兩個元素交換的動做(swap函數),而兩個元素交換在實現上是須要進行3次的賦值操做,因此會給整個過程形成大量的時間浪費,因此咱們將對上面在算法的實現上進行一個改進,經過改進以後能夠大大的縮短直接插入排序算法的所須要的時間。
改進的思想: 其實就是經過直接的賦值操做代替大量的數組元素間的互換操做,具體的實現請看下面的演示
首先仍是從第2個元素開始排序,此次咱們先將6這個元素拷貝出來一份,然
後再與左邊的8進行比較,6副本比8小,將8往右移動,再將6副本指針往左移動
直接將6副本賦值給當前所指向的這個位置,此時前面2個元素排序完畢
考慮第3個元素,仍是先將其複製一份,2副本比左邊的8小,將8往右移動,
將2副本指針往左移動
2副本又比左邊的6小,將6往右邊移動一次,將2副本指針往左移動
直接將2副本賦值給當前所指向的這個位置
前面3個元素排序完畢
再來考慮第4個元素,首先仍是先將其拷貝一份,3副本比左邊的8小,直接
將8往右移動,將3副本指針往左移動
3副本又比左邊的6小,將6往由移動,3副本指針往左移動
此時3副本比左邊的2大,這個位置合適,將3副本賦值給當前所指向的這個位置
至此前面的4個元素排序完畢,依次類推
由此能夠知道通過上面的方法以後,減小了兩個元素之間的交換操做,大大縮短了時間。
算法的實現以下:
1 /*********************************** 直接插入排序算法實現 ********************************/ 2 template<typename T> 3 void insertSort (T a[], int count) 4 { 5 /* 找到a[i]這個元素的合適插入位置,由於第一個元素前面沒有元素,沒法進行比較,因此從第二個元素開始 */ 6 for (int i = 1; i < count; i++) { 7 int j; 8 T copy = a[i]; // 將須要插入到左邊有序序列的元素拷貝出來做爲一個副本 9 for (j = i; j > 0 && a[j - 1] > copy; j--) { 10 a[j] = a[j - 1]; // 若是條件知足,直接前一個元素賦值給後面的元素 11 } 12 a[j] = copy; // 找到該元素的合適位置以後直接賦值便可 13 } 14 } 15 /**********************************************************************************************/
咱們將一系列的元素之間的交換變成了賦值操做,大大的縮短了排序所須要的時間,能夠大大提升程序運行的效率。
五、總結
(1)插入排序的時間複雜度是O(n^2)級別
(2)插入排序的內層循環是能夠提早終止的,由於只要找到了合適的位置,將元素插入到該位置後就能夠終止本次循環了。
(3)若是須要進行排序的數組序列原本就是一個很是有序的狀態,那麼插入排序執行起來的效果將比選擇排序快上不少,由於插入排序的內層循環將大大的減小時間,而選擇排序內層循環每一次都會循環到底,因此在時間上將遠遠超過插入排序,因此當須要排序的數組序列原本就是一個很是有序的狀態,那麼內層的循環基本上不用作了,這樣會大大提高效率。當須要進行排序的序列幾乎接近於有序時,插入排序的時間複雜度將會變爲n級別。