Skip to main content

快速排序

时间复杂度:

O(n^2) ~ O(nlog2n)

最坏情况下:每次选择的基数都是当前序列中的最值,使得每次划分都有一个空表,另一个表为原表长度减一。所以复杂度是 O(n^2)。
最好情况下:每次选择的技术都可以等分序列,需要经过 log2n 趟划分,所以时间复杂度为 O(nlog2n)。

原理(降序):

随机挑选或指定数组中的某个数,将其视为基准数据,然后把它排放在正确的位置。
由于基准数据已经正确排列,不需要额外处理,所以此时以基准数据为边界进行切片,得到两个数组,然后依次对左右两个数据重复执行即可。

步骤(降序):

1、在数据集中定义一个基准数据为 x,最左侧数据为 left,最右侧数据为 right,然后开始循环执行步骤 2、3。
2、从 right 位置开始往左遍历,直到获取第一个比基准数据小的数据,若没有则退出循环,若有则将此值赋值给 left,此时 left + 1。
3、从 left 位置开始往右遍历,直到获取第一个比基准数据大的数据,若没有则退出循环,若有将此值赋值给 right, 此时 right - 1。 4、此时基准数据已经找到了位置,不需要再移动它了。所以可以按照基准数据为边界,划分出左右两个切片数组,分别执行步骤 1。

https://github.com/czasg/strualgo/blob/main/algo/sort/quick.go
package sort

import (
"github.com/czasg/strualgo/basis"
)

func QuickSortASC[Number basis.Number](nums []Number) []Number {
newNums := make([]Number, len(nums))
for index, num := range nums {
newNums[index] = num
}
var quickSortASC func(nums []Number)
quickSortASC = func(nums []Number) {
if len(nums) < 2 {
return
}
left := 0
right := len(nums) - 1
x := nums[left]
for {
for left < right && nums[right] >= x {
right--
}
if left >= right {
break
}
nums[left] = nums[right]
left++
for left < right && nums[left] <= x {
left++
}
if left >= right {
break
}
nums[right] = nums[left]
right--
}
nums[left] = x
quickSortASC(nums[:left])
quickSortASC(nums[right+1:])
}
quickSortASC(newNums)
return newNums
}