快速排序算法

快速排序是20世纪最伟大的算法之一,其核心算法思想可以用在学校上体育课,按身高排列的场景来举例:

  1. 选择一个同学作为参照基准点(可随便选择);
  2. 分成两组:比这个同学矮的,站左边;反之站右边;
  3. 对左、右两个分组重复上面的过程,直到各组只剩一个人
  4. 拼接结果:左+基准值+右

实现难点:

不创建新数组的情况下,如何对原有数据进行分区排序?

 答案是使用交换法,过程如下:

  1. 选择一个pivot(为方便描述,选择第一个)
  2. 使用i(左指针)、j(右指针)从两侧向中间移动:
    i找到第一个大于pivot的数
    j找到第一个小于pivot的数
    arr[i]和arr[j]进行交换,然后继续缩小范围
  3. 当i、j交叉时,停止交换,以j作为新的分界点;
  4. 递归对左右两侧排序

一个改善可读性的条件语句: 

do{ 代码块 } while(条件)

do... while 语句其实是 while 语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如果条件为真,就会重复执行循环体,否则退出循环。

 

代码实现:

复制代码
function quickSort(arr, low = 0, high = arr.length - 1) {
  if (low < high) {
    let pivotIndex = partition(arr, low, high);
    quickSort(arr, low, pivotIndex);   // 排序左半部分(注意这里是 pivotIndex,而不是 pivotIndex - 1)
    quickSort(arr, pivotIndex + 1, high); // 排序右半部分
  }
  return arr;
}

function partition(arr, low, high) {
  let pivot = arr[low]; // 选择第一个元素作为基准
  let i = low - 1, j = high + 1;

  while (true) {
    do { i++; } while (arr[i] < pivot); // 找到左侧第一个 ≥ pivot 的元素
    do { j--; } while (arr[j] > pivot); // 找到右侧第一个 ≤ pivot 的元素

    if (i >= j) return j; // 指针交叉,返回分区点
    [arr[i], arr[j]] = [arr[j], arr[i]]; // 交换两个元素
  }
}

// 测试
let arr = [3, 6, 8, 10, 1, 2, 1];
console.log(quickSort(arr)); // 输出: [1, 1, 2, 3, 6, 8, 10]
复制代码
posted @   我是格鲁特  阅读(204)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示