排序算法 - 插入排序(Insertion sort)


插入排序對於少量元素的排序是很高效的,而且這個排序的手法在每個人生活中也是有的哦。
你可能沒有意識到,當你打牌的時候,就是用的插入排序。

概念

從桌上的牌堆摸牌,牌堆內是雜亂無序的,但是我們摸上牌的時候,卻會邊摸邊排序,借用一張算法導論的圖。

每次我們從牌堆摸起一張牌,然后將這張牌插入我們左手捏的手牌里面,在插入手牌之前,我們會自動計算將牌插入什么位置,然后將牌插入到這個計算后的位置,雖然這個計算轉瞬而過,但我們還是嘗試分析一下這個過程:

  1. 我決定摸起牌后,最小的牌放在左邊,摸完后,牌面是從左到右依次增大
  2. 摸起第1張牌,直接捏在手里,現在還不用排序
  3. 摸起第2張牌,查看牌面大小,如果第二張牌比第一張牌大,就放在右邊
  4. 摸起第3張牌,從右至左開始計算,先看右邊的牌,如果摸的牌比最右邊的小,那再從右至左看下一張,如果仍然小,繼續順延,直到找到正確位置(循環)
  5. 摸完所有的牌,結束
    所以我們摸完牌,牌就已經排完序了。
    講起來有點拗口,但是你在打牌的時候絕對不會覺得這種排序算法會讓你頭疼。
    這就是傳說中的插入排序。

想象一下,假如我們認為左手拿的牌和桌面的牌堆就是同一數組,當我們摸完牌以后,我們就完成了對這個數組的排序。

示例

上圖就是插入排序的過程,我們把它想象成摸牌的過程。
格子上方的數字:表示格子的序號,圖(a)中,1號格子內的數字是5,2號格子是2,3號格子是4,以此類推
灰色格子:我們手上已經摸到的牌
黑色格子:我們剛剛摸起來的牌
白色格子:桌面上牌堆的牌

  1. 圖(a),我們先摸起來一張5,然后摸起來第二張2,發現25小,於是將5放到2號格子,2放到1號格子(簡單的人話:將2插到5前面)
  2. 圖(b),摸起來一張4,比較4和2號格子內的數字545小,於是將5放到3號格子,再比較4和1號格子內的24大於24小於5,於是這就找到了正確的位置。(說人話:就是摸了張4點,將45交換位置)
  3. 圖(c)、圖(d)、圖(e)和圖(f),全部依次類推,相信打牌的你能夠看懂。
    看到這里,我相信應該沒人看不懂什么是插入排序了,那么插入排序的代碼長什么模樣:

Insertion Sort (seq)

	// 從第2個元素開始
	for j = 2 to seq.length
		key = seq[j]
		// 將seq[j]插入到已排序的seq[1..j-1]中
		i = j - 1
		while i > 0 and seq[i] > key
			seq[i + 1] = seq[i]
			i = i - 1
		seq[i + 1] = key

這就是傳說中的插入排序的模板了,拿一種語言來套用吧。

Python版

def sort(seq):
	for j in range(1, len(seq)):
		key = seq[j]
		i = j - 1
		while i >= 0 and seq[i] > key:
			seq[i + 1] = seq[i]
			i = i - 1
		seq[i + 1] = key
	return seq

Python源碼:Github-Syler-Fun-插入排序

Java版

public static void sort(int[] seq) {
    for (int i, j = 1; j < seq.length; j++) {
        int key = seq[j];
        i = j - 1;
        while (i > 0 && seq[i] > key) {
            seq[i + 1] = seq[i];
            i = i - 1;
        }
        seq[i + 1] = key;
    }
}

Java源碼:Github-Syler-Fun-插入排序
非常的簡單吧,其他語言的寫法也都簡單,不再贅述。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM