【数据结构】深入浅出讲解计数排序【图文详解,搞懂计数排序这一篇就够了】

news2024/11/29 2:48:16

计数排序

  • 前言
  • 一、计数排序算法核心思路
    • 映射 概念补充
    • 绝对映射
    • 相对映射
  • 二、计数排序算法核心实现步骤
  • 三、码源详解
  • 四、效率分析
    • (1)时间复杂度 — O(Max(N,range))
    • (2)空间复杂度 — O(range)



前言

计数排序是一种 非比较排序。计数排序又称为 鸽巢原理 ,是对哈希直接定址法的变形应用


一、计数排序算法核心思路

在这里插入图片描述


映射 概念补充

每个值跟其位置建立出一个关系

绝对映射

数值是几就映射出下标是几。如上图

若数组中数据的大小范围并不是乖乖的从0-1,那么这是再采用绝对映射,则会产生很大的空间浪费。
在这里插入图片描述
那么就有了相对映射的概念

相对映射

在这里插入图片描述
通过遍历原数组,找出min值,将 a[i] 的值 - min值 【即 a[ i ] - min 】就是对应 数组count[ ]的下标了,遍历到一个就令该下标( 对应a[i]的值 )下的 count [ ] 值++计数



二、计数排序算法核心实现步骤

  1. 遍历一遍数组 => 得出min和max值 => 确定数的范围

  2. 确定范围 => 确定需要开辟的数组的大小

  3. 开辟大小为range的空间count [ ] (避免了 绝对映射 那样的空间的浪费) 。用作统计 需排序的数组a[i] 中每个数据出现的次数
    【注意:要进行初始化!!否则待会遍历计数数组中,那些并没有统计到有这个数出现的次数的位置,将以该内存原来的值(随机数)进行填入】

  4. 遍历待排序的数组 => 统计数组中每个数据出现的次数 => 通过 a[i]-min 找到对应下标在 count 中的对应下标 => 对该下标的值对应++进行计数

  5. 遍历计数数组,根据统计到的每个数的次数count[i],就拷贝回去原数组count[i]次,i+min:对应回原数组中的值,while()循环覆盖原数组



三、码源详解

//计数排序——非比较排序
void CountSort(DataType* a,int n) {
    //遍历一遍数组 => 得出min和max值 => 确定数的范围
	int min = a[0]; int max = a[0];
	for (int i = 0; i < n; i++) {
		if (a[i] < min) {
			min = a[i];
		}
		if (max < a[i]) {
			max = a[i];
		}
		//确定范围 => 确定需要开辟的数组的大小
		int range = max - min + 1;    //[min,max]左闭右闭,所以+1

		//开辟大小为range的空间,避免了 绝对映射 那样的空间的浪费
		DataType* count = (DataType*)malloc(sizeof(DataType)*range);
		if (count == NULL) {
			perror("malloc fail");
			exit(-1);
		}
		//内存重置 将count数组中的值都初始化为0,重置数组大小为sizeof(DataType) * range
		//要进行初始化,否则待会遍历计数数组中,那些并没有统计到有这个数出现的次数的位置,将以该内存原来的值(随机数)进行填入
		memset(count, 0, sizeof(DataType) * range);

		                                        //数组中的值
		//遍历数组 => 统计数组中各数据出现的次数 => 通过 a[i]-min 找到对应下标在 count 中的对应下标 => 对该下标的值对应++进行计数
		for (i = 0; i < n; i++) {
			count[a[i] - min]++;
		}

		//排序
		//遍历计数数组,根据统计到的每个数的次数count[i],就拷贝回去原数组count[i]次,覆盖原数组
		//遍历数组
		int j = 0;     //放外面,遍历a[] j记录的数值 不会别被清
		for (i = 0; i < range; i++) {
		while (count[i]--){             //count[i]=0的进不了循环
			a[j++] = i + min;             //i+min:对应回原数组中的值
		}
		}
	  }
}


四、效率分析

总体特点:比较小众

  1. 适用于数据范围相对集中。
  2. 只适合整形
  3. 基数排序

(1)时间复杂度 — O(Max(N,range))

(2)空间复杂度 — O(range)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1172243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

74HC138逻辑芯片

文章目录 74系列逻辑芯片——74HC138基础信息描述特征应用范围 功能信息封装引脚基本电路 扩展性能分析 74系列逻辑芯片——74HC138 基础信息 描述 74HC138器件设计用于需要极短传播延迟时间的高性能存储器解码或数据路由应用&#xff1b;在高性能存储系统中&#xff0c;可使用…

【C语言】扫雷游戏的一步一步的实现

文章目录 一、扫雷游戏分析和设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 ⽂件结构设计 二、扫雷游戏代码实现总结 一、扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 • 使⽤控制台实现经典的扫雷游戏 • 游戏可以通过菜单实现继续玩或者退出游…

时序分解 | Matlab实现EMD经验模态分解时间序列信号分解

时序分解 | Matlab实现EMD经验模态分解时间序列信号分解 目录 时序分解 | Matlab实现EMD经验模态分解时间序列信号分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现EMD经验模态分解时间序列信号分解 Matlab语言 算法新颖小众&#xff0c;用的人很少&#xf…

面试10000次依然会问的【ReentrantLock】,你还不会?

引言 在并发编程的世界中&#xff0c;ReentrantLock扮演着至关重要的角色。它是一个实现了重入特性的互斥锁&#xff0c;提供了比synchronized关键字更加灵活的锁定机制。ReentrantLock属于java.util.concurrent.locks包&#xff0c;是Java并发API的一部分。 与传统的synchro…

如何使用CodeceptJS、Playwright和GitHub Actions构建端到端测试流水线

介绍 端到端测试是软件开发的一个重要方面&#xff0c;因为它确保系统的所有组件都能正确运行。CodeceptJS是一个高效且强大的端到端自动化框架&#xff0c;与Playwright 结合使用时&#xff0c;它成为自动化Web、移动甚至桌面 (Electron.js) 应用程序比较好用的工具。 在本文中…

2023-11 | 短视频批量下载/爬取某个用户的所有视频 | Python

这里以鞠婧祎的个人主页为demo https://www.douyin.com/user/MS4wLjABAAAACV5Em110SiusElwKlIpUd-MRSi8rBYyg0NfpPrqZmykHY8wLPQ8O4pv3wPL6A-oz 【2023-11-4 23:02:52 星期六】可能后面随着XX的调整, 方法不再适用, 请注意 找到接口 找到https://www.douyin.com/aweme/v1/web/…

rust入门基础案例:猜数字游戏

案例出处是《Rust权威指南》&#xff0c;书中有更加详细的解释。从这个例子中&#xff0c;我们可以了解到 rust 的两个操作&#xff1a; 如何从控制台读取用户输入rust 如何生成随机数 代码格式化 编译器可在保存时对代码做格式化处理&#xff0c;底层调用 rustfmt 来实现&a…

【gpt redis】原理篇

用的黑马程序员redis课程的目录&#xff0c;但是不想听讲了。后续都是用gpt文档获取的。 1.课程介绍(Av766995956,P145) 2.Redis数据结构-动态字符串(Av766995956,P146) sds 1M是个界限 其实他是个由c语言实现的结构体 有这么几个参数 len alloc flag char[] len是实际长度 …

【漏洞复现】Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、深度利用1、反弹Shell 说明内容漏洞编号CVE-2017-5645漏洞名称Log4j Server …

Python 中的 Gzip 解压

我们将介绍Python中的gzip解压。 我们还将介绍如何使用 gzip 解压缩来解压缩压缩内容。 Python 中的 Gzip 解压 Python 中构建了许多用于压缩和解压缩目的的库&#xff0c;但我们将介绍 Gzip 库。 它是一种流行的数据压缩工具。 我们可以使用 gzip 通过将数据编码为人类无法读…

字符型液晶显示器LCD 1602的显示控制(Keil+Proteus)

前言 趁机把LCD 1602的实验完成了&#xff0c;那个电路图有几个地方没弄懂&#xff0c;但是去掉也没有报错&#xff0c;就没管了。 LCD1602_百度百科 (baidu.com)https://baike.baidu.com/item/LCD1602/6014393?frge_ala LCD1602液晶显示屏通过电压来改变填充在两块平行板之…

Python算法例5 x的n次幂

1. 问题描述 实现函数Pow&#xff08;x&#xff0c;n&#xff09;&#xff0c;计算并返回x的n次幂。 2. 问题示例 Pow&#xff08;2.1&#xff0c;2&#xff09;4.41&#xff1b;Pow&#xff08;0&#xff0c;1&#xff09;0&#xff1b;Pow&#xff08;1&#xff0c;0&…

C++——类和对象之运算符重载

运算符重载 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的xmind文件和.png文件都已同步导入至”资源“ 文章目录 运算符重载[toc] 1. 运算符重载的意义2. 函数的声明2.1 声明运算符重载的注意事项 3. 函数的调用4. const成员函数4.1 const成员函数的声明4.2 注意…

C++查漏补缺与新标准(C++20,C++17,C++11)02 C++快速回顾(二)

本内容参考C20高级编程 C风格的数组 //形如 int myArray[3]{2};一个比较新颖的获取C风格数组大小的函数std::size()&#xff0c;返回size_t类型&#xff08;在中定义的无符号整数&#xff09; #include <iostream> using namespace std;int main() {int myArray[5] {…

UML---用例图

UML–用例图 0.用例图简介 用例图是一种UML&#xff08;统一建模语言&#xff09;的图形化表示方法&#xff0c;用于描述系统的功能和行为。它可以帮助系统分析师和开发人员理解系统的需求&#xff0c;用例图由参与者、用例和它们之间的关系组成。 1.用例图的组成部分 系统…

【RabbitMQ】RabbitMQ 消息的可靠性 —— 生产者和消费者消息的确认,消息的持久化以及消费失败的重试机制

文章目录 前言&#xff1a;消息的可靠性问题一、生产者消息的确认1.1 生产者确认机制1.2 实现生产者消息的确认1.3 验证生产者消息的确认 二、消息的持久化2.1 演示消息的丢失2.2 声明持久化的交换机和队列2.3 发送持久化的消息 三、消费者消息的确认3.1 配置消费者消息确认3.2…

订单业务和系统设计(一)

一、背景简介 订单其实很常见&#xff0c;在电商购物、外卖点餐、手机话费充值等生活场景中&#xff0c;都能见到它的影子。那么&#xff0c;一笔订单的交易过程是什么样子的呢&#xff1f;文章尝试从订单业务架构和产品功能流程&#xff0c;描述对订单的理解。 二、订单业务…

飞书开发学习笔记(二)-云文档简单开发练习

飞书开发学习笔记(二)-云文档简单开发练习 一.云文档飞书开发环境API 首先还是进入开放平台 飞书开放平台&#xff1a;https://open.feishu.cn/app?langzh-CN 云文档相关API都在“云文档”目录中&#xff0c;之下又有"云空间",“文档”&#xff0c;“电子表格”&a…

LLM系列 | 26:阿里千问Qwen模型解读、本地部署

引言 简介 预训练 数据来源 预处理 分词 模型设计 外推能力 模型训练 实验结果 部署实测 对齐 监督微调(SFT) RM 模型 强化学习 对齐结果(自动和人工评估) 自动评估 人工评估 部署实测 总结 引言 人生自是有情痴&#xff0c;此恨不关风与月。 ​ 今天这篇小…

从零开始:开发你的第一个抖音小程序

抖音小程序提供了独特的机会&#xff0c;能够让你将自己的创意和内容传播给数百万的抖音用户。本文将带你走一趟开发抖音小程序的旅程&#xff0c;从零开始&#xff0c;无需编程经验。你将了解到如何准备开发环境、创建你的第一个小程序&#xff0c;以及如何将它发布到抖音平台…