黃昏時偷來你的肋骨釀酒 百年後醉的有血有肉
目錄
原理
快速排序是冒泡排序的改進,思想是分治法。也是通過不斷比較和交換元素實現排序(每次邏輯取一個基準元素,每個基準元素參與多次循環和其他元素的交換),在排序時將較大的元素從前面直接放到基準元素的後面,將較小的元素放到基準元素的前面,每次邏輯執行完時左子序列的所有元素均小於右子序列的所有元素,也就是進行了分區操作,然後繼續對左右子序列分別執行該邏輯(遞歸)以此類推。
上述過程中,“該邏輯”就是一次遞歸的過程。
舉例
示例數組:{11, 3, 6, 25, 15, 1, 27}
設置基準元素base設置爲data[0],設置兩個指針分別從首部和尾部開始移動,進行循環遍歷,噹噹前元素值>base時,當前元素和data[right]交換,即移動該元素到基準元素的右側,噹噹前元素值<base時,當前元素和data[left]交換,即移動該元素到基準元素的左側...
具體過程依次如下:
原:11, 3, 6, 25, 15, 1, 27 base=11,left=0,right=5,當前元素arr[i]=3,3<11,3和11即3和data[left]交換:
第一次邏輯:
3, 11, 6, 25, 15, 1, 27
3, 6, 11, 25, 15, 1, 27
3, 6, 11, 27, 15, 1, 25
3, 6, 11, 1, 15, 27, 25
3, 6, 1, 11, 15, 27, 25
第一次邏輯結束,開始分區遞歸,左序列:3, 6, 1,base=3;右序列:15, 27, 25,base=15。
左側開始執行遞歸邏輯:
左側第一次:3, 1, 6
左側第二次:1, 3, 6
右側開始執行遞歸邏輯:
右側第一次:15, 25, 27 注意細節避免無意義操作,如27和自己進行交換。
從上述過程來看,整個執行了8次數據交換。
代碼實現
package main
import "fmt"
var count int // 計算交換次數
func quickSort3(arr []int) []int {
if len(arr) <= 1 {
return arr
}
base := arr[0] // 將數組的第一個元素定義爲基準比較元素
left, right := 0, len(arr)-1 // 兩個指針
for i := 1; i <= right; {
if arr[i] > base {
if i != right { // 自己和自己就不用交換了,該判斷可有效減少不必要的交換
// 將大於比較元素的放到右邊
arr[i], arr[right] = arr[right], arr[i]
count++
}
right--
} else {
if i != left {
// 將數組中小於比較元素的數放到左邊
arr[i], arr[left] = arr[left], arr[i]
count++
}
left++
i++
}
}
quickSort3(arr[:left])
quickSort3(arr[left+1:])
return arr
}
func main() {
var sortArray = []int{11, 3, 6, 25, 15, 1, 27}
fmt.Println("排序前:", sortArray)
quickSort3(sortArray)
fmt.Println("排序後:", sortArray)
fmt.Printf("共發生數據交換:%d 次", count)
}
控制檯
排序前: [11 3 6 25 15 1 27]
排序後: [1 3 6 11 15 25 27]
共發生數據交換:8 次
Process finished with exit code 0