js 快速排序

175 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情

前言

快速排序现在是基本需要掌握基础算法。在使用中快速排序是个高效且不浪费空间的排序算法。因为快速排序使用分治的思想。基本都是在面试的时候又要拿出来温故而知新一下。

题目:数组 [38, 5, 47, 15, 44, 26, 27] 进行从小到大进行排序。

解题思路

  • 选择基准数,一般选择基准数可以选择第一位元素或者中间数,也可以随机选择一个数
  • 设置2个指针,一前一后的两个指针。一个指向最后一位,一个指向第一位,先从右往左找比基准数小的值,再从左往右找比基准数大的值,然后置换,直到左右指针指向同一位置即结束一轮
  • 不断的递归,重复上面的的过程,让基准数的左侧数组和右侧的数组都完成排序。
  • 重复每轮的操作,直到基准值的左侧只有一个数据则结束。

解题步骤:

第一轮,选择3为基准,遍历到 2 小于基准,那么需要将 2 转移到基准之前。

将 2 和 3 的位置置换:[2, 44, 38, 5, 47, 15, 3, 26, 27] ,记录基准值位置应是 2 ,基准值被置换位置为 3 (暂存位置)

循环完后,将基准值置换回真实位置[2, 3, 38, 5, 47, 15, 44, 26, 27],此时 3左边都小于3 右边都大于3

第二轮:拆分成2个数组继续循环处理: [2] 和 [38, 5, 47, 15, 44, 26, 27]

第三轮: [38, 5, 47, 15, 44, 26, 27] 继续获取基准值 38,拆出2个数组 [5,15,26,27] 和[44,47]

这样一直重复操作下去...

JS 代码实现过程

function sortKuaisu(ary) {
    sortKuaisu_quick(ary, 0, ary.length - 1)
    console.log(ary);
}
​
// 获取基准数的索引数
function sortKuaisu_getIndex(ary, low, hight) {
    let pivot = ary[low] //默认第一位是基准数
    let i = low;
    let j = hight;
​
    while (i < j) {
        //从右往左找一个比基准小的数 (先从右往前找)
        while (ary[j] >= pivot && i < j) {
            j--;
        }
        // 从左往右找一个比基准小的数
        while (ary[i] <= pivot && i < j) {
            i++;
        }
        // 交换这个两个数据
        swap(ary, i, j)
    }
    // i==j时,交换数,使得排序好的数都分别在基准数两侧
    swap(ary, low, i)
    return i
}
​
function swap(ary, l, i) {
    let temp = ary[l];
    ary[l] = ary[i];
    ary[i] = temp;
}
​
function sortKuaisu_quick(ary, low, hight) {
    if (low < hight) {
        let index = sortKuaisu_getIndex(ary, low, hight)
​
        sortKuaisu_quick(ary, low, index - 1)
        sortKuaisu_quick(ary, index + 1, hight)
    }
}