快速排序
快速排序主要体现了分治思想;
选择一个元素为pivot, 使pivot左边的元素都小于pivot,右边的元素都大于等于pivot
然后对左右两部分也进行上述操作
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
array := []int{2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4}
QuickSort(array)
fmt.Println(array)
}
func QuickSort(array []int) {
rand.Seed(time.Now().Unix())
quickSort(array, 0, len(array)-1)
}
func quickSort(array []int, left, right int) {
if left < right {
partitionIndex := partition(array, left, right)
quickSort(array, left, partitionIndex-1)
quickSort(array, partitionIndex+1, right)
}
}
/**
划分
以下标为left的元素为pivot, 在[left, right]范围内,使
比pivot小的元素在pivot左边
比pivot大的元素在pivot右边
*/
func partition(array []int, left, right int) int {
pivot := array[left]
for left < right {
for left < right && array[right] > pivot {
right--
}
if left < right {
array[left] = array[right]
}
for left < right && array[left] <= pivot {
left++
}
if left < right {
array[right] = array[left]
}
}
array[left] = pivot
return left
}
快速排序最优时间复杂度为O(nlogn)
最坏时间复杂度为O(n^2), 原数组本来就升序或降序
体现在递归调用树的高度上,高度为n使最坏情况,高度为logn为最优情况
我们期望每次划分都是均等的,但这只是期望而已
随机快速排序
随机快速排序使对快速排序的优化
随机选取元素作为pivot
代码体现在
randIdx := rand.Int() % (right - left + 1)
swap(array, left, left+randIdx)
完整代码
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
array := []int{2, 3, 8, 7, 1, 2, 2, 2, 7, 3, 9, 8, 2, 1, 4}
QuickSort(array)
fmt.Println(array)
}
func QuickSort(array []int) {
rand.Seed(time.Now().Unix())
quickSort(array, 0, len(array)-1)
}
func quickSort(array []int, left, right int) {
if left < right {
// 随机选择元素与下标为left的进行交换
randIdx := rand.Int() % (right - left + 1)
swap(array, left, left+randIdx)
partitionIndex := partition(array, left, right)
quickSort(array, left, partitionIndex-1)
quickSort(array, partitionIndex+1, right)
}
}
func swap(array []int, i, j int) {
array[i], array[j] = array[j], array[i]
}
/**
划分
以下标为left的元素为pivot, 在[left, right]范围内,使
比pivot小的元素在pivot左边
比pivot大的元素在pivot右边
*/
func partition(array []int, left, right int) int {
pivot := array[left]
for left < right {
for left < right && array[right] > pivot {
right--
}
if left < right {
array[left] = array[right]
}
for left < right && array[left] <= pivot {
left++
}
if left < right {
array[right] = array[left]
}
}
array[left] = pivot
return left
}