JavaScript算法-计数排序(非比较型)

计数排序

一般遇到排序我们首先会想比较大小,比如冒泡排序插入排序合并排序快速排序等.排序过程都需要去对比,寻找参照物然后确定顺序位置.

这时候如果有一个参照物,它本身就是有序的,我们只要将对应的元素放置进去,那么完全放置进去后呈现的就是排序好的.

计数排序思想

1.计数排序是利用数组下标作为参照物确定元素位置

2.运用下标作为参照即参与排序的元素可以变成数组下标,那么就要求被排元素必须是整数

计数排序过程

  • 描述

1.有一组整数序列 A,找到A中的最大值 max

2.新建累计数组B, B.length 为 max+1 ,这样的话B的最后一个元素下标为max

3.数组B值以0填充,开始计数, A中元素出现一次, 对应的B位置值加一,计算下标值在A中出现的频次

4.把B中每个元素与之前元素进行累加,表示已占用空间,奇妙发生在此,当前占用空间-1即是元素排序后存在的下标位置,然后自身计数-1,因为会有重复数据

4.新建写回数组C, 长度与A一致, 把在B中排序完成集合写回C

  • 图解

原生数组A

A数组
62243351

新建数组B, 取A中最大值6加上一为B长度,以零填充

B数组
0123456
0000000

数组B对A中的值进行计数

B数组计数
0123456
0122111

B数组元素进行累加,表示已占用位置

B数组累计
0123456
0135678

新建数组C 用于回写排序元素,长度与A一致.

我们先分析几个便于理解

  1. B[0]=0,已占据0空间, 即A中不存在这个元素
  2. B[1]=1,已占据一个空间即 1-1=0   C[0]=1

以上是根据B的下标顺序来分析的,回写我们需要根据A中元素,A中第一个为6,在B中对应下标6,值为8,表示已占据8个空间,回写C[8-1] = 6

C回写数组
01234567
1(8)2(3)2(2)3(6)3(5)4(4)5(7)6(1)

注释:值后小括号表示回写顺序

  • 代码实现
function counting_sort(A){
    const max = Math.max(...A)
    let B = Array.from({length:max+1}).fill(0); //创建累计数组,并填充0
    let C = new Array(); //创建回写数组

    A.forEach( (_,i) => B[A[i]]++) //累计数组频次计算

    for(let i=1; i<B.length; i++){
        B[i] = B[i-1]+B[i] //累计数组占位累计
    }

    for(let i=0; i<A.length; i++){
        const p = B[A[i]]-1; //记录回写位置
        B[A[i]]-- //新回写位置
        C[p] = A[i]
    }
    return C
}

 

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值