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数组
6 2 2 4 3 3 5 1

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

B数组
0 1 2 3 4 5 6
0 0 0 0 0 0 0

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

B数组计数
0 1 2 3 4 5 6
0 1 2 2 1 1 1

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

B数组累计
0 1 2 3 4 5 6
0 1 3 5 6 7 8

新建数组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回写数组
0 1 2 3 4 5 6 7
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

 

 

 

 

 

 

你可能感兴趣的:(JavaScript算法)