插入排序也是一種非常容易理解的算法,核心思想就是每次將新的元素往原本有序的數組中插入。
算法思路
假設有下面一組數據,需要從小到大升序排列。
插入排序的算法是
1. 進行多輪迭代。
2. 每一次迭代的前提是將當前的數值插入到前面已經排序好的子數組當中。
也許描述有寫抽象,但用顯示當中玩撲克牌的經驗可以很好地類比插入排序。
比如你手裏已經有一堆牌。
5、6、J、K
如果你再抓到一張 9,那麼你會怎麼安放呢?
你一定會插入到 6 與 J 之間
5、6、<- 9 -> 、J、K
現在,整個牌面仍然是有序的,以後的操作都是如此的。
那麼,實際上用插入排序時,我們應當將一個數組從左到右切割成有限個有序子數組,然後重複應用插入排序的邏輯直到結束。
圖例示意:
Python 代碼演示:
def insert_sort(srcArr):
size = len(srcArr)
for i in range(1,size):
key = srcArr[i];
j = i -1;
while key < srcArr[j] and j >= 0:
srcArr[j+1] = srcArr[j]
j -= 1
srcArr[j+1] = key
return srcArr
if __name__ == "__main__":
arr = [3,2,8,4,1,6,5]
print("=======================")
print(arr)
result = insert_sort(arr)
print("=======================")
print(result)
運行結果如下:
=======================
[3, 2, 8, 4, 1, 6, 5]
=======================
[1, 2, 3, 4, 5, 6, 8]
可以看到,排序結果正確。
上面的代碼很簡單,稍微難於理解的可能是 while 循環體中的那一段。
其實,插入排序能夠插入,後面的數組都需要向後挪一個位置。
用 C++ 很容易用鏈表實現這個操作,斷開鏈接,再接上新的值的鏈接就好了。
而在 Python 中,需要給 List 中的數字提前挪窩,所以最後給指定位置賦值,就相當於插入了一樣。
時間複雜度
用大 O 表示法,選擇排序的時間複雜性度是 .
看看最壞的情況,如果一個數組完全逆序的話,每一次插入都要移動前面的元素,那麼需要進行多少次移動呢?
1 + 2 + 3 + ... + n-1=(n^2)/2
用大O 計數法,省略常數項就是 。
最好的情況是什麼呢?
那就是整個數組已經有序了,並不需要插入,保持現狀就好了,時間複雜度就是