选择算法中利用了快速排序的方法,达到了线性的时间复杂度
RandomizedSelect函数返回切片a的下标p到r中,第i小的数,下面是用GO语言的实现
主要思路和随机快排类似,不过随机快排需要对分割出的两个子序列进行处理,而选择算法只需要对一个进行处理实现了线性的复杂度
package order
import (
"math/rand"
)
//RandomizedSelect 返回数组中第i小的元素,i=0表示最小
func RandomizedSelect(a []int, p, r, i int) int{
if p == r {
return a[p]
}
q := randomPartitoin(a, p, r)
k := q - p //k表示上一个函数返回的主元在p~r中排第几小
if k == i {
return a[q]
}
if k > i { //在左边找
//fmt.Println("p",p, "q-1", q-1, "i", i)
return RandomizedSelect(a, p, q - 1, i)
}
//在右边找
return RandomizedSelect(a, q + 1, r, i - k - 1)
}
//返回值是主元素的下标
func partition(a []int, p, r int) (q int) {
x := a[p]
i := p
for j := p + 1; j <= r; j++ {
if x >= a[j] {
i = i + 1
a[i], a[j] = a[j], a[i]
}
}
a[i], a[p] = a[p], a[i]
return i
}
func randomPartitoin(a []int, p, r int) (q int) {
i := p + rand.Intn(r - p + 1)
a[i], a[p] = a[p], a[i]
return partition(a, p, r)
}