计数排序1

理解:

根据原数据中相等数出现的次数进行排序,原数据的每一个值对应了桶中的每个索引,索引指向的值就是该索引出现的次数,再依次将数据从桶中弹出,即可完成排序


代码:


// 计数排序     根据数组中相同数据出现的次数来排序
// 转换之后数组中的数据会变成桶的索引,  桶中每个索引指向的值就表示该索引出现的次数
function countSort(arr) {
    // 特殊数据处理
    if (arr == null || arr.length < 2) {
        return
    }
    // 取得数组中的最大值
    let max = arr[0]
    for (let i = 1; i < arr.length; i++) {
        max = Math.max(max, arr[i])
    }
    // 根据最大值开辟一个辅助空间   桶bucket
    // 为了使得桶的索引值能够取到最大值     桶的长度为max+1
    let bucket = new Array(max + 1)
    // 在桶每个位置上开辟一个空间   用来存放原数组中的数据  这样写是为了保持稳定性
    // [ [], [], [], [] ]
    for (let i = 0; i < bucket.length; i++) {
        bucket[i] = []
        
    }

    // 将数组中的数据插入到桶中对应索引的位置上
    // [ [0...0], [1...1], [2...2], [3...3] ]
    for (let i = 0; i < arr.length; i++) {
        // 数据从尾部插入到每个位置     保持稳定性
        bucket[arr[i]].push(arr[i])  
    }
    // 此时桶中的数据已经有序   并且相等数据的相对位置保持不变

    // 原数组索引
    let j = 0
    // 遍历桶的每个位置
    for (let i = 0; i < bucket.length; i++) {
        // 当桶中每个位置上还有数据时继续循环
        while (bucket[i].length > 0) {
            // 将桶每个位置上的数据覆盖到原数组中
            // 每个位置上的数据从头开始弹出     保持稳定性
            arr[j++] = bucket[i].shift()
        }
    }
}

性能:

  • 时间复杂度:O(N)
  • 空间复杂度:O(M),辅助空间桶bucket
  • 稳定性:原数据依次存入桶中,再从桶中依次弹出,可以保持稳定性

局限性:

  • 原数据必须有范围:由于是根据数据最大值开辟辅助空间桶bucket,所以数据必须有范围,且不宜过大。
  • 原数据可能需要特殊调整:桶bucket的索引值表示原数据的值,索引指向的数据表示该索引出现的次数。由于索引是从0开始,如果原数据中出现负数或者不从0开始,原始数据需要做特殊处理,使其与桶的索引相互对应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值