插入排序
一、算法介紹
插入排序,一般我們指的是簡單插入排序,也可以叫直接插入排序。就是說,每次把一個數插到已經排好序的數列里面形成新的排好序的數列,以此反復。
插入排序屬於插入類排序算法。
除了我以外,有些人打撲克時習慣從第二張牌開始,和第一張牌比較,第二張牌如果比第一張牌小那么插入到第一張牌前面,這樣前兩張牌都排好序了,接着從第三張牌開始,將它插入到已排好序的前兩張牌里,形成三張排好序的牌,后面第四張牌繼續插入到前面已排好序的三張牌里,直至排序完。
舉例說明
插入排序一個 4 個元素的數列:4 2 9 1
[]表示排好序
第一輪: [4] 2 9 1 拿待排序的第二個數 2,插入到排好序的數列 [4]
與排好序的數列 [4] 比較
第一輪進行中:2 比 4 小,插入到 4 前
第二輪: [2 4] 9 1 拿待排序的第三個數 9,插入到排好序的數列 [2 4]
與排好序的數列 [2 4] 比較
第二輪進行中: 9 比 4 大,不變化
第三輪: [2 4 9] 1 拿待排序的第四個數 1,插入到排好序的數列 [2 4 9]
與排好序的數列 [2 4 9] 比較
第三輪進行中: 1 比 9 小,插入到 9 前
第三輪進行中: 1 比 4 小,插入到 4 前
第三輪進行中: 1 比 2 小,插入到 2 前
結果: [1 2 4 9]
二、算法實現
Go版本
package main
import "fmt"
func InsertSort(list []int) {
n := len(list)
// 進行 N-1 輪迭代
for i := 1; i <= n-1; i++ {
deal := list[i] // 待排序的數
j := i - 1 // 待排序的數左邊的第一個數的位置
// 如果第一次比較,比左邊的已排好序的第一個數小,那么進入處理
if deal < list[j] {
// 一直往左邊找,比待排序大的數都往后挪,騰空位給待排序插入
for ; j >= 0 && deal < list[j]; j-- {
list[j+1] = list[j] // 某數后移,給待排序留空位
}
list[j+1] = deal // 結束了,待排序的數插入空位
}
}
}
func main() {
list := []int{5}
InsertSort(list)
fmt.Println(list)
list1 := []int{5, 9}
InsertSort(list1)
fmt.Println(list1)
list2 := []int{5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3}
InsertSort(list2)
fmt.Println(list2)
}
輸出
[5]
[5 9]
[1 3 4 5 6 6 6 8 9 14 25 49]
Python版本
def InsertSort(array):
for i in range(1, len(array)):
if array[i - 1] > array[i]:
temp = array[i] # 當前需要排序的元素
index = i # 用來記錄排序元素需要插入的位置
while index > 0 and array[index - 1] > temp:
array[index] = array[index - 1] # 把已經排序好的元素后移一位,留下需要插入的位置
index -= 1
array[index] = temp # 把需要排序的元素,插入到指定位置
if __name__ == '__main__':
array = [5, 9, 1, 6, 8, 14, 6, 49, 25, 4, 6, 3]
InsertSort(array)
數組規模 n 較小的大多數情況下,我們可以使用插入排序,它比冒泡排序,選擇排序都快,甚至比任何的排序算法都快。
數列中的有序性越高,插入排序的性能越高,因為待排序數組有序性越高,插入排序比較的次數越少。
大家都很少使用冒泡、直接選擇,直接插入排序算法,因為在有大量元素的無序數列下,這些算法的效率都很低。