【实现思路】
快速排序就是每次取某一个数作为参考数,每一个与他进行对比,分成大于,小于,等于,三个数组,再对大于,小于的数组进行递归排序,直到所有排完
版本1.0 取最后一个数作为参考数,将数组分为大于,小于两个数组进行递归排序
版本2.0 取最后一个数作为参考数,将数组分为大于,小于,等于三个数组,等于这个数组不再次排序
版本3.0 取随机数作为参考数,后续一样,这样能保证不会一直遭遇到最差的情况
【实现代码】版本2.0
// 入口
function search(nums = []) {
func(nums, 0, nums.length - 1)
return nums
}
// 切分数组方法,递归方法
function func(nums, l, r) {
// -1 不再处理
if (l === -1 || r === -1) return
if (l < r) {
// 对数组进行排序,返回一个数组,数组内为左数组的结束下标与右数组的开始下标
let indexArr = sort(nums, l, r)
// 根据返回的数组下标进行切分,分别排序
func(nums, l, indexArr[0])
func(nums, indexArr[1], r)
}
}
// 排序方法
function sort(nums = [], left, right) {
// 获取数组最后一位作为参考数值
const referNums = nums[right]
// 左坐标,从最左开始 left-1 代表超出左边界,左数组未开始
let l = left - 1
// 右坐标,right代表超出右边界,right这个位置已经作为参考数值,不计入
let r = right
// 循环坐标起始
let t = left
while(t < r) {
// 当数值比参考数值小,则左数组坐标向前走一步,循环坐标向前走一步
if (nums[t] < referNums) {
l++
t++
}
// 当数值比参考数值大,则右数组坐标向前走一步,将数值与最后一位互换位置
// 循环坐标不向前走,因为互换了位置,新数值未对比
else if (nums[t] > referNums) {
r--
exchange(nums, t, r)
}
// 当数值与参考数值一样大,则循环坐标向前走,其余不变
else if (nums[t] === referNums) {
t++
}
}
// 最后排序完成后,将右数组的第一位与参考数值对换位置,则右边为大数组,左边为小数组,中间为参考数值数组
exchange(nums, r, right)
// 如果左坐标未走动,则左数组不再循环
const r_left = l === left - 1 ? -1 : l
// 如果右坐标未走动,则右数组不再循环
const r_right = right === r ? -1 : r + 1
// 如果左右坐标相同,则不再递归
if (r_left === r_right) return [-1, -1]
// 返回左右坐标数组
return [r_left, r_right]
}
// 调换两个下标的数值
function exchange(nums, l, r) {
if (l === r) return
let temp = nums[l]
nums[l] = nums[r]
nums[r] = temp
}
【参考】
一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解_哔哩哔哩_bilibili