排序演算法入門之 插入排序

2022-07-03 22:42:15 字數 2645 閱讀 7956

借用《演算法導論》裡的例子,就是我們打牌的時候,每新拿一張牌都會把它按順序插入,這,其實就是插入排序。

齊姐宣告:雖然我們用打牌的例子,但是可不能學胡適先生啊。

對於陣列來說怎麼做呢?

有乙個重要的思想,叫做擋板法,就是用擋板把陣列分成兩個區間:

那麼排序分三步走:

最初擋板是在陣列的最左邊,index = 0 的位置,也就是保證了已排序區間裡乙個數都沒有,或者也可以包含乙個數啦;

核心思想就是:

依次遍歷未排序區間裡的元素,在已排序區間裡找到正確的位置插入;

重複這個過程,直到未排序區間為空。

第一步,擋板最初在這裡:

第二步,

把 2 插入已排序區間的正確位置,變成:

重複這個步驟,把 1 排好:

最後把 0 排好:

那**也很簡單:

public

void

insertionsort

(int input)

for(int i = 1; i 

input[j+1] = tmp;}}

我們來分析一下這個演算法的時空複雜度。

關於時間複雜度有兩個要點

那麼我們關心的 worst case 的情況就是:

如果陣列是近乎倒序的,每次插入都要在陣列的第乙個位置插入,那麼已排序區間內的所有的元素都要往後移動一位,這一步平均是 o(n),那麼重複 n 次就是 o(n^2).

重點是乙個峰值的概念,並不是累計使用的空間。

這裡是 o(1) 沒什麼好說的。

引入乙個概念:sorted in place,也就是原地排序

原地排序就是指空間複雜度為 o(1) 的演算法,因為沒有占用額外的空間,就是原地打轉嘛。

其實 in-place 的思想並不是只在排序演算法裡有,只不過排序演算法是乙個最廣為人知的例子罷了。本質上就是乙個節省使用空間的思想。

但是對於排序演算法,只分析它的時空複雜度是不夠的,還有另外乙個重要指標:

這個是排序演算法的乙個重要指標,意思是元素之間的相對順序是否保持了不變。

比如說:

這個陣列排序完成後這裡面的兩個 2 的相對順序沒有變,那麼這個排序就是乙個穩定排序。

那有同學可能就想,順序變了又有什麼關係呢?

其實,在實際工作中我們排序的物件不會只是乙個數字,而是乙個個的物件 (object),那麼先按照物件的乙個性質來排序,再按照另乙個性質來排序,那就不希望原來的那個順序被改變了。好像有點抽象,我們舉個例子。

比如在**交易系統裡,有買賣雙方的**,那是如何匹配的呢?

那麼一搬來說系統會維持乙個按時間排序的**序列,那麼此時只需要用乙個具有穩定性的排序演算法,再按照**大小來排序就好了。因為穩定性的排序演算法可以保持大小相同的兩個物件仍維持著原來的時間順序。

那麼插入排序是否是穩定性的排序呢?答案是肯定的。因為在我們插入新元素的時候是從後往前檢查,並不是像打牌的時候隨便插乙個位置不能保證相對順序。

大家可以看下下面的動畫

[1] 就非常清楚了~

插入排序其實是有很大的優化空間的,你可以搜一下「希爾排序」。

在剛開始學習的時候,深度固然重要,但因為廣度不夠,如果學的太深可能會很痛苦,乙個知識點就無窮無盡的延展,這並不是乙個高效的學習方式。

所以如果時間有限,就要做好深度和廣度的平衡:

保持 open minded 的心態,後期就會有質的提高。

我是小齊,紐約程式媛,終生學習者,每天晚上 9 點,雲自習室裡不見不散!

更多乾貨文章見我的 github:

[1]

排序動畫:

排序演算法之插入排序

排序演算法之插入排序 1 插入排序的思想 假設在乙個有序序列中 e 0 e i 1 這i 個元素已經排好序,則當要將第 i 1個元素 e 插入該序列時,只需將第 i 1個元素與從 e 0 開始到e i 1 元素進行比較,當發現第 j個元素 e j 在序列中應在 e 前,且 e j 1 應在e 後時,...

排序演算法之插入排序

排序演算法之插入排序 1 插入排序的思想 假設在乙個有序序列中 e 0 e i 1 這i 個元素已經排好序,則當要將第 i 1個元素 e 插入該序列時,只需將第 i 1個元素與從 e 0 開始到e i 1 元素進行比較,當發現第 j個元素 e j 在序列中應在 e 前,且 e j 1 應在e 後時,...

排序演算法之插入排序

本節主要分析插入排序演算法的直接插入排序和希爾 shell 排序 又稱縮小增量排序 1.直接插入排序 該排序是最簡單的排序方法,其基本思想是 假設待排序的記錄存放在陣列r 1.n 中。初始時,r 1 自成1個有序區,無序區為r 2.n 從i 2起直至i n為止,依次將r i 插入當前的有序區r 1....