学习经典排序算法-桶排序(bucketSort)

365 阅读3分钟

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

在上一篇文章学习了排序方法-插入排序, 另更多更文学习 JavaScript 的系列小总结更多阅读-list & 经典排序算法-list

本文来继续学习经典排序方法: 桶排序 (bucketSort), 计数排序升级版, JS 代码实现相对比较复杂, 计数排序升级版.

JS 实现排序算法-桶排序

前面有学习了计数排序, 而桶排序就是 计数排序的升级版本.

它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  • 在额外空间充足的情况下,尽量增大桶的数量使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

  • 同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要

桶排序的两个极端(最快和最慢)

  1. 最快:

当输入的数据可以均匀的分配到每一个桶中, 这时利用桶排序 最快

  1. 最慢:

    当输入的数据被分配到了同一个桶中

桶排序 JS 代码实现:

  1. 桶排序 bucketSort 函数实现
function bucketSort(arr, bucketSize) {
  if (arr.length === 0) {
    return arr
  }

  var i
  var minValue = arr[0]
  var maxValue = arr[0]
  for (i = 1; i < arr.length; i++) {
    if (arr[i] < minValue) {
      minValue = arr[i] // 输入数据的最小值
    } else if (arr[i] > maxValue) {
      maxValue = arr[i] // 输入数据的最大值
    }
  }
  // 桶的初始化
  var DEFAULT_BUCKET_SIZE = 5 // 设置桶的默认数量为5
  bucketSize = bucketSize || DEFAULT_BUCKET_SIZE
  var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1
  var buckets = new Array(bucketCount)
  for (i = 0; i < buckets.length; i++) {
    buckets[i] = []
  }

  // 利用映射函数将数据分配到各个桶中
  for (i = 0; i < arr.length; i++) {
    buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i])
  }

  arr.length = 0
  for (i = 0; i < buckets.length; i++) {
    insertionSort(buckets[i]) // 对每个桶进行排序,这里使用了插入排序
    for (var j = 0; j < buckets[i].length; j++) {
      arr.push(buckets[i][j])
    }
  }

  return arr
}

测试代码运行耗时的函数

这里 由于插入排序 bucketSort 比较适合数据量较小的数据进行排序, 故 20w+ 的数据并不太适合..

const testArrFn = function (len) {
  let arr = []
  const count = len
  for (let i = 0; i < count; i++) {
    arr[i] = Math.floor(Math.random() * 50 + 1)
  }
  return arr
}

工具: 通过测试数据(数组), 方法执行的时间

let testArr = testArrFn(len)

let len = testArr.length
/**
 * @desc 方法函数执行的时间
 */
module.exports = async function getFnRunTime(fn) {
  let startTime = Date.now(),
    endTime
  let result = await fn(testArr)
  endTime = Date.now()
  console.log(testArr, result)
  console.log(, "test_array'length: " + len, result.length,`排序耗时-total time: ${endTime - startTime}ms, `)
}
// 引入上面的 统计代码耗时的方法: 进行测试桶排序对处理2000+条数据的排序耗时:
getFnRunTime(bucketSort)

更多阅读

经典排序算法: