C语言---排序算法12---计数排序法

文章目录

计数排序(Counting Sort)是一种非比较型的整数排序算法,适用于数据范围较小的场景。其核心思想是通过统计每个元素的出现次数,然后根据次数重建有序序列。

改算法使用场景有限,是一种特殊的桶算法。

算法步骤

1、确定数据范围:找出数组中的最大值(max)和最小值(min),计算范围 range = max - min + 1。

2、创建计数数组:初始化一个长度为 range 的数组 count,统计每个元素出现的次数。

3、累加计数数组:对 count 数组进行累加操作,使 counti 表示小于等于 i + min 的元素总数。

4、反向填充有序数组:从原数组末尾向前遍历,根据 count 数组确定元素位置,放入临时数组。

5、复制回原数组:将临时数组的数据复制回原数组。

C语言实现代码

bash 复制代码
#include <stdio.h>
#include <stdlib.h>

void countingSort(int arr[], int n) {
    if (n <= 1) return;

    // 1. 确定数据范围
    int min = arr[0], max = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] < min) min = arr[i];
        if (arr[i] > max) max = arr[i];
    }
    int range = max - min + 1;

    // 2. 创建并初始化计数数组,使用calloc分配内存,在内存中初始化为0
    // 并且统计每个数出现的次数,通过 arr[i] - min 实现相对映射
    int *count = (int*)calloc(range, sizeof(int));
    for (int i = 0; i < n; i++) {
        count[arr[i] - min]++;
    }

    // 3. 累加计数数组(稳定性关键步骤)
    for (int i = 1; i < range; i++) {
        count[i] += count[i - 1];
    }

    // 4. 反向填充有序数组
    int *output = (int*)malloc(n * sizeof(int));
    for (int i = n - 1; i >= 0; i--) {
        // 从末尾开始遍历数组,根据累加位置将数据放到相应的位置上
        output[count[arr[i] - min] - 1] = arr[i];
        // 填充完毕后,计数数组相应位置减一
        count[arr[i] - min]--;
    }

    // 5. 复制回原数组
    for (int i = 0; i < n; i++) {
        arr[i] = output[i];
    }

    free(count);
    free(output);
}

// 测试代码
int main() {
    int arr[] = {4, 2, 2, 8, 3, 3, 1};
    int n = sizeof(arr) / sizeof(arr[0]);

    printf("Original array: ");
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);

    countingSort(arr, n);

    printf("\nSorted array: ");
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);

    return 0;
}

关键点说明

1、稳定性:通过反向遍历原数组并递减计数,确保相同元素的相对顺序不变。

2、处理负数:通过 arri - min 将负数映射到非负索引。

适用场景

数据范围k较小(如k ≤ 10^6),且n较大时效率显著。

整数排序(可通过偏移扩展至浮点数)。

需要稳定排序的场景(如基数排序的子程序)。

优化方向

内存优化:当数据范围k极大时,可结合桶排序思想分块处理。

并行化:统计次数和反向填充步骤可并行化处理。

扩展至浮点数:通过离散化(如乘以缩放因子)转换为整数排序。

参考视频

排序算法:计数排序【图解+代码】

相关推荐
兰令水2 分钟前
leecodecode【面试150】【2026.6.15打卡-java版本】
java·算法·面试
WWW652620 分钟前
代码随想录 打卡第五十八天
开发语言·c++·算法
pen-ai22 分钟前
【HistGBM 系列①】从决策树到梯度提升 —— GBDT 原理精讲
算法·决策树·机器学习
Black蜡笔小新31 分钟前
零代码私有化自动化AI算法训练服务器DLTM如何破解企业AI落地难题
人工智能·算法·自动化
liulilittle43 分钟前
回归物理本质:对拥塞控制实验室依赖与公平性误置的反思
网络·tcp/ip·计算机网络·算法·tcp·通信·拥塞控制
牛油果子哥q43 分钟前
unordered_set / unordered_map 底层哈希表精讲,哈希原理、哈希冲突、链地址法、源码结构、有序与无序容器终极选型全解
数据结构·算法·哈希算法·散列表
进击的荆棘1 小时前
优选算法——优先级队列
数据结构·c++·算法·leetcode·优先级队列
wen_zhufeng1 小时前
AudioX\-Turbo:面向通用音频生成的高效多模态统一框架
人工智能·算法·音视频
不会C语言的男孩1 小时前
Linux 系统编程 · 第 9 章:进程创建
linux·c语言·开发语言
AI+程序员在路上1 小时前
CSP、PP、PV、HM 在 CiA402 标准下的差异解析
linux·c语言·开发语言·嵌入式硬件