JavaScript快速排序(quickSort)算法的实现方法总结
作者:进二开物
快速排序的思想式 分治法,选一个基准点,然后根据大小进行分配,分配然完毕之后,对已经分配的进行递归操作,最终形成快速排序,所以递归也是快速排序思想的一个重要组成部分,本文主要给大家介绍了JavaScript实现快速排序的写法,需要的朋友可以参考下
什么是快速排序?
快速排序的思想式 分治法。选一个基准点,然后根据大小进行分配,分配然完毕之后,对已经分配的进行递归操作,最终形成快速排序。所以递归也是快速排序思想的一个重要组成部分。
基本思路
- 基准点: 选中基准点,一般选择数组第一项,当然也可以随机或者指定数据。
- 分区,一般分为
less/greater
或者left/right
- 递归: 对已有的分区经进行递归操作
- 合并:将已有的数据进行合并
写法一:基础写法
function quickSort(arr) { // 数组小于 1 不用排序,直接返回即可 if(arr.length <= 1) { return arr; } const p = arr[0]; // 选定数组第一个为基准点 const left = []; // 左分区 const right = []; // 右分区 // 遍历给左右分区 for(let i = 1; i < arr.length; i++) { if(arr[i] < p) { // 小于基准点放在左边 left.push(arr[i]) }else { // 大于基准点方在右边 right.push(arr[i]) } } // 合一并且对左右分区,递归处理 return quickSort(left).concat(p, quickSort(right)) }
写法二: 函数式
function quickSort(arr) { if (arr.length <= 1) { return arr; } else { const p = arr[0]; // 确定中间值 const left = arr.slice(1).filter(x => x <= p); const right = arr.slice(1).filter(x => x > p); return quickSort(left).concat(p, quickSort(right)) } }
使用 filter 过滤,偏向函数式编程,写的代码更加简洁。
写法三:随机基准值
function randomizeQuickSort(arr) { if (arr.length <= 1) { return arr; } else { const pi = Math.floor(Math.random() * arr.length); // 随机基准值索引 const p = arr[pi]; const left = arr.slice(0, pi).concat(arr.slice(pi + 1).filter(x => x <= p)); const right = arr.slice(pi + 1).filter(x => x > p); return randomizeQuickSort(left).concat(p, randomizeQuickSort(right)) } }
随机获取基准值索引,根据随机索引获基准值,所有这两个已知的值,就可以制作一个随机索引快速排序了。
写法四:三分法
function threeWayQuickSort(arr) { if (arr.length <= 1) { return arr; } else { const p = arr[0]; const left = arr.filter(x => x < p); const mid = arr.filter(x => x === p); // 获取所有的中间值,避免重复计算 const right = arr.filter(x => x > p); return threeWayQuickSort(left).concat(mid, threeWayQuickSort(right)) } }
三路法,将二路基础上,将自己看成一个中间数组,因为与自己相等的可能有很多。这样就避免了在其他数组中,还有中间数据的重复比较, 一种快速排序的优化。
排序算法的使用场景
- 大规模数据排序速度,比其他的算法要快
复杂度分析
- 快速排序的平均时间复杂度是
O(n log n)
这种复杂度是比较理想的。O(n log n)
来源是划分 O(n)
和递归 O(log n)
的组合。
更难展望
- 双轴快速排序
- 尾递归优化
小结
文本主要讲解常用算法中的快速排序的算法, 快速排序的思想很简单,就是分与合配合递归的思想。选定一个基准值,然后进行对比分离,递归这个操作,然后重新配合在一起。当然排序算法也是可以根据自己的需求进行优化的。