排序算法--计数排序

news/2025/2/6 8:27:28/

唯一种没有比较的排序(指没有前后比较,还是有交换的)。统计每个元素出现的次数,直接计算元素在有序序列中的位置,要求数据是整数且范围有限。适用于数据为小范围整数(如年龄、成绩),数据重复率较高时效率更优。可用于小范围整数排序、基数排序的底层排序(作为基数排序的稳定排序子过程)、统计频率分布(快速获取元素分布直方图)、海量数据预处理(配合外部排序处理大数据文件)

以数组的下标当做数值,有这个数的时候a[i]++;

 1绝对映射:

2相对映射:

#include <stdlib.h>
#include <assert.h>// 计数排序核心函数(稳定排序版本)
void countingSort(int arr[], int n) {if (n <= 1) return; // 无需排序// 1. 确定数据范围int max = arr[0], min = arr[0];for (int i = 1; i < n; i++) {if (arr[i] > max) max = arr[i];if (arr[i] < min) min = arr[i];}const int range = max - min + 1; // 实际数值范围// 2. 创建计数数组并初始化int* count = (int*)calloc(range, sizeof(int));assert(count != NULL);// 3. 统计每个元素出现次数for (int i = 0; i < n; i++) {count[arr[i] - min]++; // 偏移处理负数}// 4. 计算累计位置(保证稳定性)for (int i = 1; i < range; i++) {count[i] += count[i - 1];}// 5. 反向填充结果数组(关键稳定性操作)int* output = (int*)malloc(n * sizeof(int));assert(output != NULL);for (int i = n - 1; i >= 0; i--) {output[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}// 6. 复制回原数组for (int i = 0; i < n; i++) {arr[i] = output[i];}// 7. 释放内存free(count);free(output);
}
#include <stdio.h>
// 打印数组
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");
}int main() {// 测试数据(包含负数)int arr[] = {-5, 2, -3, 4, 1, 2, 8, 5, 3, -1};int n = sizeof(arr) / sizeof(arr[0]);printf("排序前: ");printArray(arr, n);countingSort(arr, n);printf("排序后: ");printArray(arr, n);return 0;
}

优化建议:

1.通过min值偏移处理负数,支持全整数范围排序

2.通过反向遍历填充输出数组,保留相同元素的原始顺序,已保证稳定性

3.动态计算range值,避免不必要的内存浪费

void countingSortSpaceOptimized(int arr[], int n) {// ...(省略范围计算步骤)...// 直接根据计数数组覆盖原数组(非稳定)int idx = 0;for (int i = 0; i < range; i++) {while (count[i]-- > 0) {arr[idx++] = i + min;}}
}


http://www.ppmy.cn/news/1569748.html

相关文章

oracle: 数据操纵语言DML/批量更新

SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于管理和操作关系数据库的标准编程语言。 sql分类: DML基本语法 DML是“Data Manipulation Language”的缩写, 即数据操纵语言 用于对数据库中的数据进行插入、更新、删除(即增删改…

Ubuntu 上可以安装ms sqlserver?

是的&#xff0c;Microsoft SQL Server 可以安装在 Ubuntu 上。自 SQL Server 2017 版本起&#xff0c;Microsoft 提供了对 Linux 的支持&#xff0c;包括 Ubuntu。以下是详细的步骤&#xff0c;介绍如何在 Ubuntu 上安装 SQL Server。 步骤 1&#xff1a;导入 Microsoft GPG …

【大数据技术】搭建完全分布式高可用大数据集群(Scala+Spark)

搭建完全分布式高可用大数据集群(Scala+Spark) scala-2.13.16.tgzspark-3.5.4-bin-without-hadoop.tgz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群Spark的详细步骤。 注意: 统一约定将软件安装包存放于虚拟机的/softwa…

安卓(android)饭堂广播【Android移动开发基础案例教程(第2版)黑马程序员】

一、实验目的&#xff08;如果代码有错漏&#xff0c;可查看源码&#xff09; 1.熟悉广播机制的实现流程。 2.掌握广播接收者的创建方式。 3.掌握广播的类型以及自定义官博的创建。 二、实验条件 熟悉广播机制、广播接收者的概念、广播接收者的创建方式、自定广播实现方式以及有…

从零开始学习安时积分法(STM32实现程序)

在STM32微控制器上实现安时积分法&#xff08;Coulomb Counting&#xff09;来估算电池的SOC&#xff08;State of Charge&#xff09;&#xff0c;需要完成以下几个步骤&#xff1a; 硬件配置&#xff1a; 使用STM32的ADC模块测量电池的电流。使用定时器模块进行时间积分。配置…

【Leetcode 热题 100】1143. 最长公共子序列

问题背景 给定两个字符串 t e x t 1 text_1 text1​ 和 t e x t 2 text_2 text2​&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 0 0。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变…

[ Spring ] Spring Boot Mybatis++ 2025

文章目录 StructureMyBatis Controller AbilitiesConfigure Plugins and RepositoriesApply Plugins and Add DependenciesMyBatis Spring PropertiesMyBatis ApplicationMyBatis BeansMyBatis MapperMyBatis Query Builder Structure this blog introduce 3 ways using mybat…

HarmonyOS NEXT:保存应用数据

用户首选项使用 用户首选项的特点 数据体积小、访问频率高、有加载速度要求的数据如用户偏好设置、用户字体大小、应用的配置参数。 用户搜选项&#xff08;Preferences&#xff09;提供了轻量级配置数据的持久化能力&#xff0c;支持订阅数据变化的通知能力。不支持分布式同…