一句话总结:
快速排序的优化就像给赛车调校——选好基准(轮胎),小规模换策略(弯道用漂移),处理重复零件(三向切分),让排序速度更快更稳!
一、基础版快速排序(先跑起来)
原理: 选基准、分区、递归处理左右
fun quickSortBasic(arr: IntArray, low: Int = 0, high: Int = arr.size - 1) {
if (low < high) {
val pivotIndex = partition(arr, low, high)
quickSortBasic(arr, low, pivotIndex - 1)
quickSortBasic(arr, pivotIndex + 1, high)
}
}
private fun partition(arr: IntArray, low: Int, high: Int): Int {
val pivot = arr[high] // 选最后一个元素为基准(有优化空间!)
var i = low - 1
for (j in low until high) {
if (arr[j] <= pivot) {
i++
arr.swap(i, j)
}
}
arr.swap(i + 1, high)
return i + 1
}
// 交换扩展函数
fun IntArray.swap(i: Int, j: Int) {
val temp = this[i]
this[i] = this[j]
this[j] = temp
}
二、优化策略(让赛车更快)
优化 1:随机选择基准(避免最坏情况)
private fun partitionOptimized(arr: IntArray, low: Int, high: Int): Int {
// 随机选基准并与末尾交换
val randomIndex = (low..high).random()
arr.swap(randomIndex, high)
return partition(arr, low, high) // 继续用基础版分区
}
优化 2:小数组用插入排序(减少递归开销)
fun quickSortOptimized(arr: IntArray, low: Int = 0, high: Int = arr.size - 1) {
if (high - low < 10) { // 小数组阈值设为10
insertionSort(arr, low, high)
return
}
val pivotIndex = partitionOptimized(arr, low, high)
quickSortOptimized(arr, low, pivotIndex - 1)
quickSortOptimized(arr, pivotIndex + 1, high)
}
private fun insertionSort(arr: IntArray, low: Int, high: Int) {
for (i in low + 1..high) {
val key = arr[i]
var j = i - 1
while (j >= low && arr[j] > key) {
arr[j + 1] = arr[j]
j--
}
arr[j + 1] = key
}
}
优化 3:三向切分(处理大量重复元素)
fun quickSortThreeWay(arr: IntArray, low: Int = 0, high: Int = arr.size - 1) {
if (high <= low) return
// 初始化三个指针
var lt = low
var gt = high
val pivot = arr[low]
var i = low + 1
while (i <= gt) {
when {
arr[i] < pivot -> arr.swap(lt++, i++)
arr[i] > pivot -> arr.swap(i, gt--)
else -> i++
}
}
// 递归处理左右
quickSortThreeWay(arr, low, lt - 1)
quickSortThreeWay(arr, gt + 1, high)
}
三、测试用例(验车)
fun main() {
// 测试用例1:普通乱序数组
val arr1 = intArrayOf(3, 1, 4, 1, 5, 9, 2, 6)
quickSortOptimized(arr1)
println(arr1.contentToString()) // [1, 1, 2, 3, 4, 5, 6, 9]
// 测试用例2:已排序数组(测试最坏情况优化)
val arr2 = intArrayOf(1, 2, 3, 4, 5)
quickSortOptimized(arr2)
println(arr2.contentToString()) // [1, 2, 3, 4, 5]
// 测试用例3:大量重复元素
val arr3 = intArrayOf(2, 2, 1, 1, 3, 3, 3)
quickSortThreeWay(arr3)
println(arr3.contentToString()) // [1, 1, 2, 2, 3, 3, 3]
// 测试用例4:空数组和单元素数组
val arr4 = intArrayOf()
quickSortOptimized(arr4) // 无异常
val arr5 = intArrayOf(5)
quickSortOptimized(arr5)
println(arr5.contentToString()) // [5]
}
四、优化效果对比
| 场景 | 基础版 | 随机基准 | 小数组优化 | 三向切分 |
|---|---|---|---|---|
| 完全有序数组 | O(n²) | O(n log n) | O(n log n) | O(n log n) |
| 大量重复元素 | O(n²) | O(n log n) | O(n log n) | O(n) |
| 随机数据 | O(n log n) | O(n log n) | O(n log n) | O(n log n) |
五、口诀
快速排序要优化,
随机基准是妙法。
小数组改插入排,
重复元素三向切!
弯道超车靠调校,
数据再大也不怕! 🚀