前面我们介绍了6种比较交换类的排序,现在我们看一下分类收集类的排序
    计数排序一种利用空间换时间的排序办法

    算法思路:
    1、根据待排序集合中最大元素和最小元素的差值范围,申请额外空间;
    2、遍历待排序集合,将每一个元素出现的次数记录到元素值对应的额外空间内;
    3、对额外空间内数据进行计算,得出每一个元素的正确位置;

    代码
    **

    1. function countSort(nums){
    2. let min = Infinity, max = -Infinity
    3. for (const num of nums) { // 确定最大最小值
    4. min = Math.min(min, num)
    5. max = Math.max(max, num)
    6. }
    7. let store = new Array(max - min + 1).fill(0)
    8. for (const num of nums) { // 计数
    9. store[num - min]++
    10. }
    11. let p = 0, res = new Array(nums.length)
    12. for (let i = 0; i < store.length; i++) { // 逐个计数还原
    13. while(store[i]--) nums[p++] = i + min
    14. }
    15. return nums
    16. }


    假如开辟的空间为k (由max(nums) - min(nums)计算得出)
    时间复杂度O(n + k)
    空间复杂度O(n)


    我们对于普通的数字比较而言这里不需要考虑稳定性
    当然如果考虑稳定性我们可以利用js的数组的特性来完成

    代码
    **

    1. function countSort(nums){
    2. let min = Infinity, max = -Infinity
    3. for (const num of nums) { // 确定最大最小值
    4. min = Math.min(min, num)
    5. max = Math.max(max, num)
    6. }
    7. let store = new Array(max - min + 1)
    8. for (const num of nums) { // 计数
    9. if(!store[num - min]) store[num - min] = [] // 当成一个队列
    10. store[num - min].push(num) // 入队列
    11. }
    12. let p = 0, res = new Array(nums.length)
    13. for (const value of store) {
    14. while(value && value.length) nums[p++] = value.shift() // 出队列
    15. }
    16. return nums
    17. }

    这样对于相同一个元素而言,他们的相对输出顺序没有发生变化