算法排序篇-7【桶排序】js解法

92 阅读2分钟

桶排序

基本思想

桶排序采用分治策略,通过设置若干个具有大小顺序的桶,每个桶对应一个数据范围,将数据平均分配到各个桶中,然后,在每个桶内部执行排序,最终按照桶的顺序将所有数据合并。

实现思路

  1. 初始化k个桶,将n个元素分配到k个桶中
  2. 对每个桶分别执行排序
  3. 按照桶的从小到大的顺序,合并数组

代码实现

function bucketSort(array, bucketSize = 5) { // bucktsize为每个桶中元素默认的数量
    if (array.length < 2) { 
        return array
    }
    const buckets = createBuckets(array, bucketSize) // 创建桶
    return sortBuckets(buckets) // 桶的排序合并
}

function createBuckets(array, bucketSize) {
    // 假设第一个值为最大值和最小值
    let minValue = array[0]
    let maxValue = array[0]
    for (let i = 1; i < array.length; i++) { // 遍历数组找到真实的最大值和最小值
        if (array[i] < minValue) {
            minValue = array[i]
        } else if (array[i] > maxValue) {
            maxValue = array[i]
        }
    }
    const bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1 // 计算桶的数量公式
    const buckets = [] // 初始化桶
    for (let i = 0; i < bucketCount; i++) { // 插入bucketCount数量个桶
        buckets[i] = []
    }
    for (let i = 0; i < array.length; i++) { // 遍历数组计算插入到哪个桶
        const bucketIndex = Math.floor((array[i] - minValue) / bucketSize) // 计算该插入哪个桶 
        buckets[bucketIndex].push(array[i]) // 将数据插入对应的桶
    }
    return buckets
}

function sortBuckets(buckets) {
    const sortedArray = [] // 结果数组
    for (let i = 0; i < buckets.length; i++) {
        if (buckets[i] != null) {
            insertionSort(buckets[i]) // 使用插入排序排序每个桶---在算法排序篇-3中实现的插入排序函数
            sortedArray.push(...buckets[i]) // 将各个桶添加到结果数组中
        }
    }
    return sortedArray
}

function insertionSort(array) {
    const { length } = array
    let temp // 存储要插入的值
    for (let i = 1; i < length; i++) { // 默认数组有一项,从1开始
        let j = i
        temp = array[i] // 存储要插入的值
        while(j > 0 && (array[j - 1] > temp)) { // 如果要插入的值的前一项比要插入的值大,则插入的前一项向后面移一位,而插入的值再与前面的值相比较,直到找到合适的位置(j),同时j索引减少到合适的位置
            array[j] = array[j - 1]
            j--
        }
        array[j] = temp // 找到合适的位置,插入要插入的值
    }
    return array
}
const array = [23,2,24,5,7,232,8,3,9,11]
console.log(bucketSort(array)); // [ 2,  3,  5,  7,   8, 9, 11, 23, 24, 232]