十大排序算法(JavaScript实现 )- 桶排序 Bucket Sort

225 阅读1分钟
  1. 十大排序算法(JavaScript实现 )- 冒泡排序 Bubble Sort

  2. 十大排序算法(JavaScript实现 )- 选择排序 Selection Sort

  3. 十大排序算法(JavaScript实现 )- 插入排序 Insertion Sort

  4. 十大排序算法(JavaScript实现 )- 希尔排序 Shell Sort

  5. 十大排序算法(JavaScript实现 )- 快速排序 Quick Sort

  6. 十大排序算法(JavaScript实现 )- 归并排序  Merge Sort

  7. 十大排序算法(JavaScript实现 )- 计数排序 Count Sort

  8. 十大排序算法(JavaScript实现 )- 桶排序 Bucket Sort

  9. 十大排序算法(JavaScript实现 )- 基数排序 Radix Sort

  10. 十大排序算法(JavaScript实现 )- 堆排序 Heap Sort

概念

桶排序是计数排序算法的升级版本。假设输入数据服从均匀分布,将数据分到有限的数量的桶里,每个桶再分别排序。

算法原理

  1. 假设有如下原始数组:[35,23,48,9,16,24,5,11,32,17] 我们可以建立五个桶,每个桶按范围顺序分别是[0,10)[10,20)[20,30)[30,40)[40,50],注意,每个桶的范围都是包含最小值,不包含最大值,最后一个桶,既包含最小值,也包含最大值

图片.png

  1. 对每个桶里面的数据进行排序

图片.png

  1. 遍历所有桶,因为每个桶都是有序的了,所以遍历所有桶也是有序的。

算法代码

/**
 * 桶排序
 * @param {number[]} arr 原始数组
 * @param {number} bucketCapacity 桶容量
 */
function bucketSort(arr, bucketCapacity = 10) {
  // 1. 先求出原始数组的最大值和最小值
  let max = arr[0]
  let min = arr[0]
  for(let i = 1; i < arr.length; i++) {
    if (arr[i] > max) {
      max = arr[i]
    }
    if (arr[i] < min) {
      min = arr[i]
    }
  }
  // 桶的数量
  const bucketCount = ~~((max - min) / bucketCapacity) + 1
  // 初始化桶里数据,是一个二维数组
  const bucketArr = Array(bucketCount).fill().map(() => [])
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i]
    // 计算当前元素应该放入哪个桶里面
    let bucketIndex = ~~((item - min) / (max - min)  * bucketCount)
    if (bucketIndex === bucketCount) {
      bucketIndex--
    }
    bucketArr[bucketIndex].push(item)
  }
  // 对每个桶进行排序,这里使用插入排序
  for (let i = 0; i < bucketArr.length;i++) {
    let itemArr = bucketArr[i]
    insertionSort(itemArr)
  }

  // 遍历每个桶
  const result = []
  let index = 0
  for(let itemArr of bucketArr) {
    for (let item of itemArr) {
      result[index++] = item
    }
  }
  return result
}
// 插入排序
function insertionSort(array) {
  for (let i = 1; i < array.length; i++) {
    let insertValue = array[i]
    let insertIndex = i - 1
    while(insertIndex >=0 && array[insertIndex] > insertValue) {
      array[insertIndex + 1] = array[insertIndex]
      insertIndex--
    }
    array[insertIndex + 1] = insertValue
  }
}