[路飞]_计数排序 - 之 整数和负数

318 阅读2分钟

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

计数排序是将一个数组的中元素出现的数量计数,从小到大,按出现次数依次显示出来。

下图中就是未排序和排序结果的展示 微信截图_20211104172130.png

计数排序是唯一个不需要交换位置排序的算法, 时间复杂度是Ο(n+k), k指的是整数的范围。

  1. 首先创建一个临时空数组,将索引表示次数,元素表示整数.
  2. 其次while循环按次数追加到结果数组里。
  3. 如果元素里有负数,需要通过数组的最小值做一个差值转换。(下面有负数的情况说明及解决方案)

正数版本

 // 基础版本
function countSort(arr){
    let temp = [],res = [] // temp给原数组元素计数     
    for(let v of arr){
        // 索引对应元素 , 值对应出现的次数
        temp[v] = (temp[v] || 0) +1    
    }
    for(let i = 0 ; i < count.length; i++){
        // 取出次
        let count = temp[i]
        while(count > 0){
         // 按次数打印原数组的元素 
         res.push(i)
         count++
        }
    }
    return res
}

思考如果元素中出现负数怎么办?

我们会将数组中的最小值取到,每个元素和最小值做一个差值,最小的与自己的差值正好是0 可以当索引,在最终结果打印时,通过差值还原成本来的数值。

负数版本

// 元素出现负数版本
function countSort(arr){
    let temp = [],res = [] // temp给原数组元素计数 
    let min = Math.min(...arr) // 取出最小值, 
    for(let v of arr){
        // 索引对应元素 , 值对应出现的次数 索引需要借助min 转换一下 
        temp[v - min] = (temp[v - min] || 0) +1    }
    for(let i = 0 ; i < count.length; i++){
        // 取出次数
        let count = temp[i]
        while(count > 0){
         // 按次数打印原数组的元素 
         res.push(i + min) // 原数组对应的元素需要min 还原
         count++
        }
    }
    return res
}

结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~