原理
有一組數,先認定第一個元素爲有序序列,後面的都是無序序列,然後拿無序序列的第一個元素和有序序列的最後一個元素比,如果後者大於前者,那麼插入到有序序列的末尾;如果前者大於後者,那麼繼續和有序序列的倒數第二個元素比,以此類推插入到有序序列中,直到有序序列是全部元素時排序完畢。
簡單舉例
有一組數{8,18,6,88},需要從小到大排列出來,步驟如下:
1,先認定一個有序序列{8},即第一個元素;再認定一個無序序列{18,6,88},即第一個後面的元素。然後開始;
2,取出無序序列的第一個元素18,用18和有序序列的最後一個,即和8比較,18>8,因此將18放在8的後面,此時有序序列爲{8,18} ;
3,取出無序序列的第一個元素6,用6和有序序列的最後一個,即和18比較,6<18,因此6放在18的前面,繼續拿6和8(18的上一個元素)比較,6<8,所以把6放在8的前面,有序序列就兩個元素,所以這一趟就比完了,此時有序序列爲{6,8,18} ;
4,拿88和有序序列的最後一個元素18比較,88>18,所以這一趟比較完了,88直接放在18後面,此時有序序列的元素是四個{6,8,18,88},即已經比較完了。
注意
1,數組長度爲n的話,需要遍歷n-1趟,走完每趟都會給有序序列插入一個數,無序序列會少一個數,遍歷第m趟時有序序列已經存在m個數,每趟最多需要遍歷的次數就是n-m。
2,如果需要有大到小排列出來,那麼建議每次拿無序序列的第一個元素先和有序序列的第一個元素比,因爲此時如果前者大於後者,那麼就不需要繼續比下去了,直接可以進行下一趟遍歷。
上代碼
/* 由小到大排列 */
func main() {
arr := [...]int{79, 1, 90, 38, 76, 33, 17, 88}
fmt.Println("排序完成:", sortArrC1(arr[:]))
}
func sortArrC1(arr []int) []int {
fmt.Println("傳入數組:", arr, "長度:", len(arr))
for i := range arr {
fmt.Println("key=", i)
preIndex := i - 1
currentV := arr[i]
for preIndex >= 0 && arr[preIndex] > currentV {
arr[preIndex+1] = arr[preIndex]
preIndex -= 1 // 繼續跟有序序列的其他值比較(從後往前)
}
arr[preIndex+1] = currentV //如果比有序序列的最後一個元素大,直接跟到有序序列的後面即可
fmt.Println("i=", i, "\t當前數組=", arr)
}
return arr
}
打印:
傳入數組: [79 1 90 38 76 33 17 88] 長度: 8
key= 0
i= 0 當前數組= [79 1 90 38 76 33 17 88]
key= 1
i= 1 當前數組= [1 79 90 38 76 33 17 88]
key= 2
i= 2 當前數組= [1 79 90 38 76 33 17 88]
key= 3
i= 3 當前數組= [1 38 79 90 76 33 17 88]
key= 4
i= 4 當前數組= [1 38 76 79 90 33 17 88]
key= 5
i= 5 當前數組= [1 33 38 76 79 90 17 88]
key= 6
i= 6 當前數組= [1 17 33 38 76 79 90 88]
key= 7
i= 7 當前數組= [1 17 33 38 76 79 88 90]
排序完成: [1 17 33 38 76 79 88 90]
黃昏時偷來你的肋骨釀酒 百年後醉得有血有肉