快速排序之JavaScript版

基本思想

  • 分治法
  • 每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。
  • 在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的,都是 O(n^2),它的平均时间复杂度为 O(nlogn) 。

直接上代码

// quickSort.js
/**
 * 快速排序(一)
 * 修改元素数组
 * 时间复杂度O(nlogn)
 * @param arr 待排序数组
 * @param left 数组最低位
 * @param right 数组最高位
 */
const quickSort1 = function (arr, left, right) {
  // 递归出口是数组长度 <= 1
  if (!(arr instanceof Array) || arr.length <= 1) {
    return
  }
  if (left > right) return

  let x = arr[left] // 取最左值作为比较的基准值x
  let i = left
  let j = right // i,j 为哨兵

  while(i != j) {
    // 从右往左开始找比x小的
    while(i < j && x <= arr[j]) {
      j--
    }
    // 从左往右开始找比x大的
    while (i < j && x >= arr[i]) {
      i++
    }

    // i, j停下来后且i<j时,交换值
    if (i < j) { 
      let temp = arr[i]
      arr[i] = arr[j]
      arr[j] = temp
    }
  }
  // i, j相遇时,哨兵归位
  arr[left] = arr[i]
  arr[i] = x
  // 分治法,递归
  quickSort1(arr, left, i-1) // 基准值左边区间同样方法处理
  quickSort1(arr, i+1, right) // 基准值右边区间同样方法处理
}

/**
 * 快速排序(二)
 * 不修改元素数组,返回排序后的数组
 * 时间复杂度O(nlogn)
 * @param arr 待排序数组
 */
const quickSort2 = function (arr) {
  // 递归出口是数组长度 <= 1
  if (arr.length <= 1) return arr

  let mid = Math.floor(arr.length / 2) 
  let midVal = arr[mid] // 取中间值作为比较的基准值x

  const left = [] // 存放 < 基准值的数
  const right = [] // 存放 >= 基准值的数

  for (let i = 0; i < arr.length; i++) {
    if (i === mid) continue // 基准值过滤掉
    if (arr[i] < midVal) {
      left.push(arr[i])
    }
    if (arr[i] >= midVal) {
      right.push(arr[i])
    }
  }
  // 分治法,同样的方法处理子数组,把结果拼接起来返回
  return quickSort2(left).concat(midVal, quickSort2(right))
}

module.exports = {
  quickSort1,
  quickSort2
}

参考资料:《啊哈算法》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值