经典排序算法之【计数排序】

       互联网行业的小白,写博客的目的是为了记录自己的学习过程、对自己学习中所犯的错误做一个总结。由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!

1. 原理

计数排序是一个非基于比较的排序算法,它的优势在于在对一定范围内的整数排序时,它的复杂度为 O ( n + k ) Ο(n+k) O(n+k)(k是整数的范围),快于任何比较排序算法。其思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。

2. 步骤

  • 找出序列中最大值和最小值,开辟Max-Min+1的辅助空间
  • 扫描一遍原始序列,以当前值 - Min作为下标,将该下标的计数器加1
  • 扫描一遍计数器序列,按顺序把值收集起来

3. 演示

在这里插入图片描述

4. 模板

C语言

void countingsort(int *Array, int size_A){
    int Max = Array[0];  // 序列的最大值
    int Min = Array[0];  // 序列的最小值
    for(int i = 0; i < size_A; i++){
        if(Array[i] >= Max) Max = Array[i];
        if(Array[i] <= Min) Min = Array[i];
    }
    int Range = Max - Min + 1;  // 临时开辟辅助空间的大小
    int* temp = new int[Range];  // 动态开辟空间大小为Range的temp序列
    memset(temp, 0, sizeof(int) * Range);  //初始化
    for(int i = 0; i < size_A; i++)
        temp[Array[i] - Min] += 1;  // 当前值 - Min 作为下标的计数
    int index = 0;  // 控制变量
    for(int i = 0; i < Range; i++){   // 遍历辅助空间
        while(temp[i]--){  // 下标处的数值是几,说明该数出现了几次
            Array[index++] = i + Min;  // 将下标处的数对应回原序列
        }
    }
    delete[] temp;  // 回收空间
}

python版

def countingSort(Array):
    Max = max(Array)  # 序列的最大值
    Min = min(Array)  # 序列的最小值
    Range = Max - Min + 1  # 临时开辟辅助空间的大小
    temp = [0] * (Range)  # 开辟辅助空间
    for i in range(len(Array)):
        temp[Array[i] - Min] += 1  # Array[i] - Ain是将该数对应到辅助空间的下标
    index = 0  # 控制变量
    for i in range(0, Range):  # 遍历辅助空间
        while(temp[i] > 0):  # 下标处的数值是几,说明该数出现了几次
            Array[index] = i + Min  # 将下标处的数对应回原数组
            index += 1
            temp[i] -= 1
    return Array

5. 分析

  • 计数排序是一种以空间换时间的排序算法,并且只适用于待排序列中所有的数较为集中时。如序列[3, 2, 1, 999]就不适用于计数排序,需要开辟1000个辅助空间,太过于浪费。

  • 计数排序是稳定的:具有相同值的两个元素在输出数组中的相对次序与它们在输入数组中的相对次序相同。也就是说,对两个相同的数来说,在输入数组中先出现的数,在输出数组中也位于前面。

  • 计数排序经常被作为基数排序算法的一个子过程。

图片来源:https://visualgo.net/en

在这里插入图片描述

码字不易,您的支持就是我坚持下去的动力,一起加油哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值