基礎算法——排序【一】
阿新 • • 發佈:2019-01-13
for 最好 min 選擇排序 步驟 是否 tro UNC sel ,在各種情況下算法時間復雜度都為O(n2),空間復雜度為O(n);
排序可以說時最基礎的算法之一,排序就是將數據按照某種邏輯重新排列的過程,比如從大到小排序、從小到大排序;排序非常常見比如有購物車物品的排序、歷史訂單的排序等等;算法我們比較關心的主要有兩點:時間復雜度與空間復雜度,排序算法一樣;這篇文章只介紹幾種基本的排序算法:冒泡排序、插入排序、選擇排序;
選擇排序
算法邏輯上分為已排序未排序兩個區間,從當前列表中選擇最小的元素與當前列表第一個元素交換位置,從列表剩余元素中找到最小元素與列表第二個元素交換位置如此重復執行的算法為選擇排序算法;
選擇排序與數據的初始狀態無關,每次查找最小元素值時都會與數組中元素進行交換位置,因此選擇排序為非穩定排序算法
func SelectionSort(data [] int) { n := len(data) if n <= 1 { return } for i := 0; i < n; i++ { //最小元素索引 min := i for j := i + 1; j < n; j++ { if data[j] < data[min] { min = j } } //交換元素,交換後未已排序數據 data[i], data[min] = data[min], data[i] } }
插入排序
與選擇排序類似在邏輯上列表分為已排序和未排序兩個區間,初始時已排序區間未為左邊第一個元素,插入排序的核心為從右邊未排序區間中選擇元素插入到左邊合適的位置,直到已排序列表長度等於原始列表長度;插入排序算法的關鍵步驟為元素比較與元素的移動,當從未排序端拿數據插入到已排序端時已排序端可能會存在大量的數據移動;
與選擇排序不同的是列表初始狀態對插入排序的性能影響很大,當列表初始狀態有序度很高時插入排序並不需要大量移動數據,從中可以看出插入排序為原地排序算法、算法是穩定的;
算法最好情況下時間復雜度為:O(n)、平均、最壞復雜度為:O(n2);
func InsertionSort(data [] int) { n := len(data) for i := 1; i < n; i++ { value := data[i] //查找插入位置 var j int for j = i - 1; j >= 0; j-- { if data[j] > value { //數據後移 data[j+1] = data[j] } else { break } } data[j+1] = value } }
冒泡排序
每次比較相鄰兩個元素是否滿足,否則交換相鄰兩個元素,每次冒泡至少一個元素移動到它所屬位置,重復N次完成列表排序;
冒泡操作核心為項鏈元素交換,空間復雜度為O(1),為原地排序算法;算法是穩定的,最好情況時間復雜度為為O(n),平均與最壞情況時間復雜度為:O(n2);
func BubbleSort(data [] int) {
n := len(data)
for i := 0; i < n; i++ {
//是否有數據交換,用於當某輪中數據已排序時退出循環
flag := false
for j := 0; j < n-1-i; j++ {
if data[j] > data[j+1] {
//冒泡
data[j], data[j+1] = data[j+1], data[j]
flag = true
}
}
if !flag {
break
}
}
}
基礎排序算法特性
參考資料: 《算法四》
基礎算法——排序【一】