数据结构与算法之 快速排序

280 阅读3分钟

本文为原创文章,未获授权禁止转载,侵权必究!

本篇是 数据结构与算法 系列第 1 篇,关注专栏

前言

排序算法 用于对一组数据按照特定顺序进行排列。排序算法 的选择对于数据处理的效率和性能至关重要。快速排序(Quick Sort) 是一种基于 分治策略 的排序算法,运行高效,应用广泛。

快速排序 的核心操作是 哨兵划分,其目标是:选择数组中的某个元素作为 基准数,将所有 小于 基准数的元素 移到左侧 ,而 大于 基准数的元素 移到右侧。 执行步骤大致如下:

  1. 取数组最左端元素作为基准数,初始化两个指针 left 和 right 分别指向数组的两端。
  2. 设置一个循环,在每轮中使用 leftright)分别寻找第一个比基准数大(小)的元素,然后交换这两个元素。
  3. 循环执行步骤 2. ,直到 left 和 right 相遇时停止,最后将基准数交换至两个子数组的分界线。

简单版快排

简单版快排 相较于 标准版快排 性能上会较差,原因是创建了更多的空间。执行步骤大致如下:

  1. 取数组最左端元素作为基准数,初始化左右两个空数组
  2. 设置一个循环,逐个对比基准数,比它小的放至左边,否则放至右边
  3. 递归对左右两个数组进行排序
  4. 将已排序的左边数据、基准数、已排序的右边数据进行合并后返回
// 定义数据
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)

标准版快排流程

快速排序.png

数据结构与算法 练习

learn-algorithm

数据结构与算法 系列

  1. 数据结构与算法之 快速排序