快速排序
快速排序
思想
快速排序的核心思想就是,每次在下标 left 到 right范围内标记一个中间值mid,然后使用双指针在left和right这个区域中进行排序,使其mid左边都是小于它的,右边都是大于它的,划分成两个区域后再依次对着两个区域再进行递归调用。
mid可以随便取,一般取left 或 right的值。
我们的函数声明应该是 quickSort(left,right,arr)
需要完成的效果:
第一轮需要完成的效果

这里mid取得right的值。第一轮排序后0的左边都是小于它的,右边都是大于等于它的。
具体逻辑
- 判断是否right<=left,满足这个条件直接return,因为只有一个元素
- 设置begin = left,end = right
- 设置mid值(我这里取的是right)
- 设置标记变量isChange=false,检测本次是否发生交换
- while right>left 里面进行双指针操作
以[4,2,9,8,5,1,-6,0]为例,我们取的mid = arr[right] = 0,所以要先走左边left找到一个比mid大的值与right进行覆盖
go left:很明显 4 >0 覆盖得到 [4,2,9,8,5,1,-6,4] ,此时right--因为要走right了,left依然指向arr[0]:4这个地方,等待右边找到一个比mid小的值进行覆盖
go right:-6 < 0 覆盖得到 [-6,2,9,8,5,1,-6,4],此时left++,right不变,再走下次大循环
go left: 2 > 0 覆盖得到 [-6,2,9,8,5,1,2,4]
go right: 从arr[6]:2 走到 arr[1]:2 此时left == right 结束小循环,把mid赋值给arr[left或right]得到 [-6,0,9,8,5,1,2,4] ,结束大循环
[-6,0,9,8,5,1,2,4]这是第一次排序的结果 接下来对 begin到left-1 左区域进行排序,left+1到end右区域进行排序
JS代码
let count = 0
let arr = [4,2,9,8,5,1,-6,0]
quickSort(0,arr.length-1,arr)
function quickSort(left,rigth,arr){
if(rigth<=left)return;
let begin = left,end = rigth
let temp = arr[rigth]
let isChange = false//如果本次区域(左或右)没有发生一次交换,则该区域有序,不需要再递归了
while(left<rigth){
while(left<rigth){
if(arr[left]<temp){
left++
}else{
arr[rigth--]=arr[left]
isChange = true
break;
}
}
while(left<rigth){
if(arr[rigth]>temp){
rigth--
}
else{
arr[left++]=arr[rigth]
isChange = true
break;
}
}
}
if(!isChange)return;
arr[left]=temp
console.log(`第${++count}次排序后:${arr}`);
quickSort(begin,left-1,arr)
quickSort(left+1,end,arr)
}

浙公网安备 33010602011771号