[路飞]-桶排序、 归并排序

269 阅读2分钟

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

桶排序

桶排序顾名思义就是若干个桶,根据自定义的映射函数将元素放入桶中,保证每个桶里的元素分配均匀。分配完毕之后将桶里的元素进行排序,最后桶里的元素的依次输出到数组里,桶排序就结束了。

桶中元素如果分配不均匀,集中在一个桶里则桶排序失效。

步骤

  1. 算出桶的个数(最大值-最小值)/ 数组长度 + 1取整
  2. 按照个数初始化数组
  3. 按照映射关系(元素的值- 最小值 ) / 数组长度给每个桶添加元素
  4. 每个桶内进行排序(任意的排序方法都行)
  5. 排序完毕后将桶里的元素 依次添加到数组里
代码示例
function bucketSort(arr){
    let min = Math.min(...arr)
    let max = Math.max(...arr)

    //1. 算出桶的个数
    const bucketNum = Math.floor((max-min) / arr.length )+ 1
    //2. 初始化桶
    const bucketArr= new Array(bucketNum)
    for(let i = 0; i< bucketNum;i++){
        bucketArr[i] = new Array()
    }
    //3. 给每个桶添加元素
    for(let i = 0; i < arr.length; i++){
        const num = Math.floor ((arr[i] - min) / arr.length) //相当于一个映射函数 根据这个规则将元素放进桶里
        bucketArr[num].push(arr[i])
    }

    //4. 每个桶进行排序
    let index = 0
    // 桶排序的稳定性建立在每个桶内用的什么排序算法
    bucketArr.map(bucket => bucket.sort()).forEach(bucket => {
        for(let i = 0; i< bucket.length; i++){
            arr[index++] = bucket[i]
        }
    })

    //5. 将桶里的元素 依次添加到数组里
    console.log(arr);
}


bucketSort([18,11,28,45,23,50])

归并排序

将数组从中间拆分左右两个数组,左右两个数组继续做拆分,直到数组中剩下一个元素。此时两两合并,按照小的优先合并原则。

步骤

  1. 首先从数组中间分割, 然后将分割好的数组再次在中间分割,直到数组长度为1
  2. 将分割的数组依次进行队首比较 小的放入res数组里
  3. 最终res数组就是从小到大的顺序排列了
代码示例
function mergeSort(arr){
    const n = arr.length
    if(n < 2)return arr
    const mid = n >> 1  // 首先从数组中间分割
    return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)))
}

function merge(left , right){
    const res = []
    //  将分割的数组进行队首比较 小的放入res数组里
    while(left.length && right.length){
        if(left[0] <= right[0]){
            res.push(left.shift())
        }else{
            res.push(right.shift())
        }
    }
    // left right 分别对剩余元素的存储
    while(left.length) res.push(left.shift())
    while(right.length)res.push(right.shift())
    return res
}

console.log(mergeSort([5,4,3,2,1]));