知识内容参考《大话数据结构》P417
实例代码:
package main
import (
"fmt"
"math/rand"
"time"
)
func QSort(a []int, low int, high int) {
if low < high {
pivot := Partition2(a, low, high) //依据某一个临界值(左侧的小于此值,右侧的大于此值),
QSort(a, low, pivot-1) //对左侧递归排序
QSort(a, pivot+1, high) //对右侧递归排序
}
}
//------------------------------------------------------------
//错误写法
func Partition(a []int, low int, high int) int {
temp := a[low]
for {
if low >= high {
break
}
if temp <= a[high] {
high--
} else {
temp, a[high] = a[high], temp //交换的并非比较的值,而是 数组内 大于 小于temp的值
}
if temp >= a[low] {
low++
} else {
temp, a[low] = a[low], temp
}
}
return low
}
//------------------------------------------------------------
//方法2
func Partition2(a []int, low int, high int) int {
temp := a[low] //取最左侧的值作为比较值(移位之后的数组,参考值会在中间位置: 小于值 参考值 大于值 )
for {
if low >= high {
break
}
//取最左侧的值作为比较值,因此从右端开始
for low<high&&temp <= a[high] {//必须有 low<high 否则 对于high来说,若以temp完成分割,会继续前移,出现越界
high--
}
a[low], a[high] = a[high], a[low]
for low<high&&temp >= a[low] {//必须有 low<high 否则 对于low来说,若以temp完成分割,会继续后移,出现越界
low++
}
a[low], a[high] = a[high], a[low]
}
return low
}
//方法1
func Partition1(a []int, low int, high int) int {
//取左侧的索引值为参考值,注意:数组在交换的同时参考值也会随之交换
temp := low
for {
if low >= high {
break
}
for low < high && a[temp] <= a[high] {
high--
}
a[temp], a[high] = a[high], a[temp]
temp = high //更新位置
for low < high && a[temp] >= a[low] {
low++
}
a[temp], a[low] = a[low], a[temp]
temp = low //更新位置
}
return low
}
func main() {
rand.Seed(time.Now().UnixNano())
arr := make([]int, 0)
for i := 0; i < 25; i++ {
arr = append(arr, rand.Intn(1000))
}
fmt.Println("排序之前的切片为:")
fmt.Println(arr)
low := 0
high := len(arr) - 1
QSort(arr, low, high)
fmt.Println("通过快速排序方法排序之后的切片为:")
fmt.Println(arr)
}
另外一种思路:
package main
import (
"fmt"
"math/rand"
"time"
)
func quickSort(left, right int, arr []int) {
l := left
r := right
value := arr[(l+r)/2]
//进行一次排序
for l < r {
for arr[l] < value {
l++
}
for arr[r] > value {
r--
}
if l >= r {
break
}
arr[l], arr[r] = arr[r], arr[l]
if arr[l] == value { //为了应对相同的数字
r--
}
if arr[r] == value { //为了应对相同的数字
l++
}
}
//非常重要,如果不加,卡在 l=r处不会动了,形成死递归。
if l == r {
l++
r--
}
//左递归
if l < right {
quickSort(l, right, arr)
}
//右递归
if r > left {
quickSort(left, r, arr)
}
}
func main() {
rand.Seed(time.Now().UnixNano())
arr := make([]int, 0)
for i := 0; i < 25; i++ {
arr = append(arr, rand.Intn(1000))
}
fmt.Println("排序之前的切片为:")
fmt.Println(arr)
quickSort(0, len(arr)-1, arr)
fmt.Println("排序之后的数据为:")
fmt.Println(arr)
}
➢了解更多Go语言知识:https://study.163.com/course/introduction/1210620804.htm