快排
算法要点
- 设立基准值,以基准值为中心,根据分治思路把大于基准值放一边,小于基准值放另一边。
- 递归上一步的操 作。
基准值获取想法
1.从最左或最右或中间
2.基准值的获取直接影响了时间算法的复杂度,理想情况是0(nlogn),最坏情况是n^2。
3.从这个角度来看,快排算法是不稳定的
尾递归优化
最右的基准值
func patitionLeft(data []int, begin, end int) int{
pivot := data[end]
leftShit := begin
for i:=begin; i<end; i++ {
if data[i] >= pivot {
data[i], data[leftShit] = data[leftShit], data[i]
leftShit++
}
}
data[end], data[leftShit] = data[leftShit], data[end]
fmt.Println(begin, end)
fmt.Println(data)
return leftShit
}
func quickSortLeft(data []int, begin, end int) {
if begin >= end {
return
}
pivotIndex := patitionLeft(data, begin, end)
quickSortLeft(data, begin, pivotIndex-1)
quickSortLeft(data, pivotIndex+1, end)
}
最左基准值
func partitionRight(data []int, begin, end int) int{
pivot := data[begin]
shift := end
for i:=end; i > begin; i-- {
if data[i] > pivot {
data[i], data[shift] = data[shift], data[i]
shift--
}
}
data[shift], data[begin] = data[begin], data[shift]
return shift
}
func quickSortRight(data []int, begin, end int) {
if begin > end {
return
}
pivot := partitionRight(data, begin, end)
quickSortRight(data, 0, pivot-1)
quickSortRight(data, pivot+1, end)
}
中间某个基准值
改变begin的索引位置就行
go 并发版本
func quickSort_go(a []int, lo, hi int, done chan struct{}, depth int) {
if lo >= hi {
done <- struct{}{}
return
}
depth--
p := partition(a, lo, hi)
if depth > 0 {
childDone := make(chan struct{}, 2)
go quickSort_go(a, lo, p-1, childDone, depth)
go quickSort_go(a, p+1, hi, childDone, depth)
<-childDone
<-childDone
} else {
quickSort(a, lo, p-1)
quickSort(a, p+1, hi)
}
done <- struct{}{}
}
参考
https://colobu.com/2018/06/26/implement-quick-sort-in-golang/
有疑问加站长微信联系(非本文作者)