「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
快速排序
介绍
快速排序 通过这个名字,我们就知道他是排序算法中最快的 排序算法。
因为网上有很多 快速排序 ,这里介绍其中一种是 通过 二分递归 来进行的 快速排序。
快速排序方式一 的原理就是:
给定一组数据,通过二分的方式 获取该数据中的中间下标位置(基准点) 所对应的值(基准点的值)弹出,然后从剩余数据中,从左到右依次进行比对,将小于该值的值放置左侧,将大于该值的值放置右侧。
完成后,在对左侧 和 右侧 的数据项 再分别进行上述步骤,递归进行,直到最后左侧和右侧的数据数量都为 1 时停止。再进行最后的连接操作即可。
步骤详解
上图是给定的数据
const arr = [15,5,25,20,30,10]
-
先判断数据的长度,是否小于等于 1,如果是则直接返回该数据
if (arr.length <= 1) return arr -
获取 基准点 及 基准点的值:
通过 二分的方式 获取上图中该数据中 中间下标 (也叫 基准点)
// 基准点 const midIndex = Math.floor(arr.length / 2) const valArr = arr.splice(midIndex, 1) // 基准点的值 const midIndexVal = valArr[0]由该公式得到 上图的 基准点 为下图紫色部分:3
且 基准点的值 为:20
-
与 基准点的值 比较
上图中蓝色部分的数据,通过循环,分别对 基准点的值 的进行比对,将小于 基准点的值 的数据放置一个新的左侧数组中,将大于 基准点的值 的数据放置一个新的右侧数组中。
const left = [] // 存放比基准点小的数组 const right = [] // 存放比基准点大的数组 arr.forEach((item) => { item < midIndexVal ? left.push(item) : right.push(item) }) -
递归
通过上述步骤后,我们会得到结果如下图所示:
-
left:
[15, 5, 10] -
midIndexVal:
[20] -
right:
[25, 30]
再对左侧 和 右侧 的数据 分别再进行上述 重复递归 的操作后,即可得到最终结果,这里注意,有个技巧,就是通过 js中数组的 concat 方法进行连接。
return quickSort(left).concat(midIndexVal, quickSort(right)) -
-
最终结果为:
[ 5, 10, 15, 20, 25, 30 ]
完整代码
const quickSort = (arr) => {
if (arr.length <= 1) return arr
// 取基准点
const midIndex = Math.floor(arr.length / 2)
// 取基准点的值,splice(index,1) 则返回的是含有被删除的元素的数组。
const valArr = arr.splice(midIndex, 1)
const midIndexVal = valArr[0]
const left = [] // 存放比基准点小的数组
const right = [] // 存放比基准点大的数组
// 遍历数组,进行判断分配
arr.forEach((item) => {
item < midIndexVal ? left.push(item) : right.push(item)
})
// 递归执行以上操作,对左右两个数组进行操作,直到数组长度为 <= 1
return quickSort(left).concat(midIndexVal, quickSort(right))
}
总结
快速排序 方式一的优缺点:
优点:
-
很容易入门理解 快速排序
-
通过二分找到 基准点,再分别和 基准点的值 来进行比较。
-
递归
缺点:不稳定,不是一个稳定的算法