快速排序算法原理:
設置分水嶺,把小於分水嶺的數排到分水嶺左側,其餘的排到右側,遞歸的對分水嶺兩側的元素做同樣的處理
package qsort func quickSort(values []int, left int, right int) { if left < right { // 設置分水嶺 temp := values[left] // 設置哨兵 i, j := left, right for { // 從右向左找,找到第一個比分水嶺小的數 for values[j] >= temp && i < j { j-- } // 從左向右找,找到第一個比分水嶺大的數 for values[i] <= temp && i < j { i++ } // 如果哨兵相遇,則退出循環 if i >= j { break } // 交換左右兩側的值 values[i], values[j] = values[j], values[i] } // 將分水嶺移到哨兵相遇點 values[left] = values[i] values[i] = temp // 遞歸,左右兩側分別排序 quickSort(values, left, i-1) quickSort(values, i+1, right) } } func QuickSort(values []int) { quickSort(values, 0, len(values)-1) }
更簡潔的版本:
package main import "fmt" func main() { numbers := []int{6, 2, 7, 7, 3, 8, 9} //fmt.Println(numbers) QuickSort(numbers) fmt.Println(numbers) } func QuickSort(values []int) { length := len(values) if length <= 1 { return } mid, i := values[0], 1 // 取第一個元素作爲分水嶺,i下標初始爲1,即分水嶺右側的第一個元素的下標 head, tail := 0, length-1 // 頭尾的下標 // 如果頭和尾沒有相遇,就會一直觸發交換 for head < tail { fmt.Println(values, head, tail, i) if values[i] > mid { // 如果分水嶺右側的元素大於分水嶺,就將右側的尾部元素和分水嶺右側元素交換 values[i], values[tail] = values[tail], values[i] tail-- // 尾下標左移一位 } else { // 如果分水嶺右側的元素小於等於分水嶺,就將分水嶺右移一位 values[i], values[head] = values[head], values[i] head++ // 頭下標右移一位 i++ // i下標右移一位 } fmt.Printf("----{head:%d,tail:%d,i:%d,mid:%d} values:%v\n", head, tail, i, mid, values) } // 分水嶺左右的元素遞歸做同樣處理 QuickSort(values[:head]) QuickSort(values[head+1:]) }