插入排序法有幾種,書中討論的是 簡單插入排序法,也稱 直接插入排序法。算法
這種排序法能夠用抽撲克牌的過程類比。數組
咱們將手上的牌和還沒抽到的牌分別稱爲 手牌區 和 新牌區,手牌區始終是有序的。bash
當抽下一張牌後,會將新牌與手上的牌做比較,插入到合適的地方,使得手牌區維持有序,這也就是插入排序法名字的由來。優化
當最後一趟排序結束時,全部牌都進入手牌區,排序結束。spa
由此也能夠看出,插入排序法的核心就在於 插入。code
考慮抽牌的整個過程,類比數組,能夠用天然語言描述以下:cdn
從第二張牌開始,遍歷全部的牌:
拿到新牌;
遍歷手上全部的牌:
找到新牌的位置;
將新牌插到手上的牌中;
複製代碼
能夠用一張簡單的圖表示插入排序:blog
使用 C 語言實現以下:排序
void INSERTSORT(int cards[], int totalOfCards) {
for (int i = 1; i < totalOfCards; i++) {
int newCard = cards[i];
int j = i - 1;
while (j >= 0 && cards[j] > newCard) {
cards[j + 1] = cards[j];
j--;
}
cards[j + 1] = newCard;
}
}
複製代碼
對於 n 個元素的序列,插入排序一共須要 n - 1
趟排序。it
只須要一個輔助空間,即 newCard
,故空間複雜度爲 O(1)。
當數組自己是順序的,實際只在每趟的邊界處進行了比較,因此一共爲 n - 1
次;當數組自己是逆序的,那麼每次都要比較 i - 1
次(和手上的每張牌都要比較),一共是 次。
取最好與最壞的平均值約 ,因此插入排序的時間複雜度爲 O()。
由於新牌是按序進行插入的,相同值的新牌也會按順序插入到受衆,因此插入排序法是 穩定性算法。
插入排序的核心是插入,但在插入前須要在手牌中查找要插入的位置,優化插入排序,能夠着眼於優化 查找算法。
前文中是經過遍歷查找的,在改良算法中,能夠使用二分查找來尋找須要插入的位置,這種算法便稱爲 折半插入排序算法。