寫給你的快速排序,請簽收~

       黃昏時偷來你的肋骨釀酒   百年後醉的有血有肉  

目錄

原理

舉例

代碼實現


原理

快速排序是冒泡排序的改進,思想是分治法。也是通過不斷比較和交換元素實現排序(每次邏輯取一個基準元素,每個基準元素參與多次循環和其他元素的交換),在排序時將較大的元素從前面直接放到基準元素的後面,將較小的元素放到基準元素的前面,每次邏輯執行完時左子序列的所有元素均小於右子序列的所有元素,也就是進行了分區操作,然後繼續對左右子序列分別執行該邏輯(遞歸)以此類推。

上述過程中,“該邏輯”就是一次遞歸的過程。

舉例

示例數組:{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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章