本文为原创文章,未获授权禁止转载,侵权必究!
本篇是 数据结构与算法 系列第 1 篇,关注专栏
前言
排序算法
用于对一组数据按照特定顺序进行排列。排序算法
的选择对于数据处理的效率和性能至关重要。快速排序(Quick Sort)
是一种基于 分治策略
的排序算法,运行高效,应用广泛。
快速排序
的核心操作是 哨兵划分
,其目标是:选择数组中的某个元素作为 基准数
,将所有 小于
基准数的元素 移到
其 左侧
,而 大于
基准数的元素 移到
其 右侧
。 执行步骤大致如下:
- 取数组最左端元素作为基准数,初始化两个指针
left
和right
分别指向数组的两端。 - 设置一个循环,在每轮中使用
left
(right
)分别寻找第一个比基准数大(小)的元素,然后交换这两个元素。 - 循环执行步骤
2.
,直到left
和right
相遇时停止,最后将基准数交换至两个子数组的分界线。
简单版快排
简单版快排
相较于 标准版快排
性能上会较差,原因是创建了更多的空间。执行步骤大致如下:
- 取数组最左端元素作为基准数,初始化左右两个空数组
- 设置一个循环,逐个对比基准数,比它小的放至左边,否则放至右边
- 递归对左右两个数组进行排序
- 将已排序的左边数据、基准数、已排序的右边数据进行合并后返回
// 定义数据
const arr = [4, 1, 5, 2, 8, 7, 6, 3]
// 简单版 快排
function simpleQuickSort(arr) {
if (!(Array.isArray(arr) && arr.length)) {
// 需返回 []
return []
}
// 基准点 以第一个为基准
let leader = arr[0]
let left = []
let right = []
// 从第二个开始遍历
for (let i = 1; i < arr.length; i++) {
// 比基准小,放置左边,否则放置右边
if (arr[i] < leader) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
// 对左边重新排序
left = simpleQuickSort(left)
// 对右边重新排序
right = simpleQuickSort(right)
// 将基准点塞入
left.push(leader)
// 返回 已排序左边 + 基准 + 已排序右边 = 最终排序
return left.concat(right)
}
// 输出结果
console.log(simpleQuickSort(arr))
标准版快排
// 定义数据
const arr = [4, 1, 5, 2, 8, 7, 6, 3]
// 交换位置
function swap(arr, a, b) {
const temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
}
// 标准快排
function quickSort(arr, begin, end) {
if (begin >= end - 1) return
let left = begin
let right = end
do {
do {
left++
} while (left < right && arr[left] < arr[begin])
do {
right--
} while (right > left && arr[right] > arr[begin])
if (left < right) {
swap(arr, left, right)
}
} while (left < right)
// 获取基准点
let swapPoint = left === right ? right - 1 : right
// 交换位置
swap(arr, begin, swapPoint)
// 左边区间排序
quickSort(arr, begin, swapPoint)
// 右边区间排序
quickSort(arr, swapPoint + 1, end)
}
// 排序
function baseQuickSort(arr) {
if (!(Array.isArray(arr) && arr.length)) {
return
}
quickSort(arr, 0, arr.length)
}
// 执行
baseQuickSort(arr)
// 输出结果
console.log(arr)