【初阶数据结构】计数排序 :感受非比较排序的魅力

news2024/11/27 22:45:29

文章目录

  • 前言
  • 1. 什么是计数排序?
  • 2. 计数排序的算法思路
    • 2.1 绝对位置和相对位置
    • 2.2 根据计数数组的信息来确认
  • 3. 计数排序的代码
  • 4. 算法分析
  • 5. 计数排序的优缺点
  • 6.计数排序的应用场景

前言

如果大家仔细思考的话,可能会发现这么一个问题。我们学的七大排序(冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序)都是通过数组中元素之间比较进行数组中数字挪动,从而达到排序的目的。

以上的排序我们也把它们称为"比较排序"。那在本文中,我们就了解一个非比较的排序——“计数排序”。

hahaha

1. 什么是计数排序?

计数排序(Counting Sort)是一种线性时间复杂度的排序算法,它通过统计数组中元素的出现次数,来确定每个元素在排序后的数组中的正确位置。

为了让大家更好的理解理解计数排序,我给大家画一幅图:
计数排序的流程图

2. 计数排序的算法思路

  1. 🍉统计相同元素出现的次数
  2. 🍉根据统计的结果将序列回收到原来的序列中

想必上面的图已经给你一点提示了。这里就会有两个问题想问一下大家:

  1. 怎么将待排序的数组中的数字映射到计数的数组中?
  2. 如何将计数数组中的元素回写到待待排序的数组中,从而达到排序的效果?

2.1 绝对位置和相对位置

绝对位置:从数组首元素开始计算,剩余每个元素的位置都是按照数组首元素为参照的。

举个例子:数组a:[1,5,6,8,9,7,3,2,0,4],那对于计数数组来说用绝对位置就比较好,原因是这个待排序的数组a的元素最小值是为0,最大值为9,这里用绝对位置就比较舒服!

相对位置:先选取待排序数组中的最小值,以这个最小值为基准,从而给剩余的元素在计数数组中确定位置。

举个例子:数组a:[101,100,106,103,105,104],如果你这里硬是要使用绝对位置的话,你就要申请106个整型数据的空间,而我只有6个数据需要排序,开这么大的数据空间就有点得不偿失了。所以我们得采用相对位置,以数组a中的最小值(100)为基准,其余元素按照大小关系依次记录到计数数组中。

所以我建议大家使用相对位置来实现计数排序。

2.2 根据计数数组的信息来确认

我们创建了计数数组之后,我们要怎么讲信息还原到原序列中呢?

就根据我们设定的相对位置加上原本的最小值,就可以还原出待排序数组中元素的值。然后再建立一个循环,根据count数组中的位置元素的值决定循环这个相对位置加上原本的最小值多少次。

3. 计数排序的代码

#include<stdio.h>
#include<stdlib.h>

//计数排序 -- 是一个非比较的排序方式
//通过统计数组中每个数字出现的次数,通过创建一个count数组记录这些数字对应出现的次数。(利用相对位置进行对应)

void CountSort(int* a, int n)
{
	
	//1.为获得相对位置,我们要想找到数组中的最小值还要找最大值
	int min = a[0],max = a[0];
	for (int i = 1; i < n; i++)
	{
		if (min > a[i])
		{
			min = a[i];
		}

		if (max < a[i])
		{
			max = a[i];
		}
	}

	int* count = (int*)calloc(max, sizeof(int));
	if (count == NULL)
	{
		perror("calloc fail");
		return;
	}


	//统计数字出现的次数,并将其对应到count数组中
	for (int i = 0; i < n; i++)
	{
		//a[i]-min:就相当于a[i]其在count数组中的相对位置
		count[a[i] - min]++;
	}

	int j = 0;
	//根据count数组复现数字到目标数组中
	for (int i = 0; i < max; i++)
	{
		while (count[i]--)
		{
			a[j++] = min + i;
		}
	}
}

int main()
{
	int a[] = { 1,1,6,6,9,8,4,5,1,3,4,7,4 };
	int size = sizeof(a) / sizeof(int);

	CountSort(a,size);

	for (int i = 0; i < size; i++)
	{
		printf("%d ",a[i]);
	}
	printf("\n");
	return 0;
}

这个排序比较简单,大家只要注重算法的思路就行!!!

4. 算法分析

时间复杂度:计数排序的时间复杂度为 O ( n + k ) O(n + k) O(n+k),其中 n n n 是输入数组的大小, k k k 是输入数据的范围大小。由于不涉及元素之间的比较,计数排序可以在较小的数据范围内达到比比较类排序更高效的结果。

空间复杂度:额外的空间复杂度为 O ( k ) O(k) O(k),因为需要创建一个计数数组用来记录元素的出现次数和累积结果。如果 k k k 过大,则计数排序的空间消耗会很大。

稳定性:计数排序是一种稳定的排序算法,即排序后相同的元素相对位置不发生改变。这一点对于一些带有附加信息的数据排序非常有用。

5. 计数排序的优缺点

  1. 优点:
    🍉时间复杂度低:在适合的情况下,能够达到 O ( n ) O(n) O(n) 的线性时间复杂度。
    🍉稳定性:保持了相同元素的相对顺序,对数据处理有额外需求时非常有用。
  2. 缺点:
    🍇限制范围:计数排序只能用于整数类型数据不适用浮点数类型、字符类型的数据等,且适用于数据范围较小的情况。如果数据范围过大,空间复杂度会急剧增加。
    🍇额外空间:需要额外的空间来存储计数数组,尤其在范围较大时,空间消耗会非常明显。

6.计数排序的应用场景

由于计数排序对元素范围有一定限制,它更适用于以下场景:

  • 成绩统计:假设一个班级的学生成绩是 0-100 分的整数,那么使用计数排序能够快速对这些分数进行排序。

  • 投票计数:如果投票结果是有限个选项,可以用计数排序来统计每个选项的票数。

  • 基数排序的子过程:在基数排序中,计数排序通常被用作处理每一位数的排序过程。

好了,到这里本文就结束了。觉得本文对你有帮助的话,麻烦给偶点个赞吧!

haahah

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

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

相关文章

【C语言】原码 反码 补码

为什么要有原码 反码 补码的概念&#xff1f; 因为在计算机中最终只能识别机器码&#xff0c;是以 0000 0000 二进制作为表示形式&#xff0c;对于一个数&#xff0c;计算机要使用一定的编码方式进行存储&#xff0c;原码 反码 补码是机器存储一个数值的编码方式&#xff0c;最…

技术分享:A-23OH型树脂在汽车涂装废溶剂回收中的应用

在当今汽车制造业竞争激烈的环境下&#xff0c;提高生产效率、降低成本的同时&#xff0c;满足环保要求已成为各制造商追求的核心目标。水性涂料因其环保、节能等多重优势&#xff0c;在汽车涂装领域的应用日益广泛。然而&#xff0c;随之而来的喷涂废溶剂处理问题也日益凸显。…

2024年软件设计师中级(软考中级)详细笔记【7】面向对象技术(下)23种设计模式(分值10+)

目录 前言阅读前必看 第七章 面向对象技术&#xff08;下&#xff09;7.3 设计模式&#xff08;固定4分&#xff09;7.3.1 设计模式的要素7.3.2 创建型设计模式7.3.2.1 Abstract Factory&#xff08;抽象工厂&#xff09;7.3.2.2 Builder&#xff08;生成器&#xff09;7.3.2.3…

调整奇数偶数的顺序

//调整奇数偶数的顺序 //输入一个整数数组&#xff0c;实现一个函数 //使得数组中所有的奇数位于数组的前半部分&#xff0c;所有的偶数位于数组的后半部分 #include<stdio.h> void tz(int a[],int sz) {int i 0;int j 0;int q 0;int c[100] { 0 };int b[100] { 0 …

Qt第十三天:网络编程:TCP和UDP的使用

我发现了有些人喜欢静静看博客不聊天呐&#xff0c; 但是ta会点赞。 这样的人呢帅气低调有内涵&#xff0c; 美丽大方很优雅。 说的就是你&#xff0c; 不用再怀疑哦 ❤️TCP&#xff1a; 一、创建项目&#xff0c;命名为Server&#xff0c;继承QWidget 二、添加Qt设计师…

Axure重要元件三——中继器添加数据

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 本节课&#xff1a;中继器添加数据 课程内容&#xff1a;添加数据项、自动添加序号、自动添加数据汇总 应用场景&#xff1a;表单数据的添加 案例展示&#xff1a; 步骤…

算法: 模拟题目练习

文章目录 模拟替换所有的问号提莫攻击Z 字形变换外观数列数青蛙 总结 模拟 替换所有的问号 按照题目的要求写代码即可~ public String modifyString(String ss) {int n ss.length();if (n 1) {return "a";}char[] s ss.toCharArray();for (int i 0; i < n; i…

【华为HCIP实战课程十三】OSPF网络中3类LSA及区域间负载均衡,网络工程师

一、ABR SW1查看OSPF ABR为R4而非R3,因为R4连接骨干区域0,R3没有连接到区域0 R6查看OSPF路由: 二、查看3类LSA,由于R6不是ABR因此自身不会产生3类LSA 但是有区域间路由就可以看到3类LSA

分布式介绍

CAP理论 CAP理论是分布式架构中提出来的一种设计思想模型&#xff0c;全称是由Consistency、Availability、Partition Tolerance三个词组成。 C(Consistency&#xff0c;一致性):总能读到最新的写操作的结果A(Availability&#xff0c;可用性):每个请求都要在合理的时间内给出…

Spring Boot知识管理:跨平台集成方案

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

后渗透利用之vcenter

目录 vcenter介绍环境搭建历史漏洞版本信息1、直接访问2、请求接⼝ 打点CVE_2021_21972漏洞描述&#xff1a;POC&#xff1a; 后渗透获取vCenter后台重置密码Cookie登录创建管理员 获取虚拟机Hash分析快照挂载磁盘 获取Esxi 后台获取解密key获取数据库账号密码查询Esxi加密密码…

ESP32-IDF 分区表

目录 一、基本介绍1、配置结构体1.1 esp_partition_t1.2 esp_partition_iterator_t 2、常用 API2.1 esp_partition_find2.2 esp_partition_find_first2.3 esp_partition_get2.4 esp_partition_next2.5 esp_partition_iterator_release2.6 esp_partition_verify2.7 esp_partitio…

使用WPF写一个简单的开关控件

<Window x:Class"WPF练习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend/2008"xm…

适用于 vue react Es6 jQuery 等等的组织架构图(组织结构图)

我这里找的是 OrgChart 插件; 地址: GitHub - dabeng/OrgChart: Its a simple and direct organization chart plugin. Anytime you want a tree-like chart, you can turn to OrgChart. 这里面能满足你对组织架构图的一切需求! ! ! 例: 按需加载 / 拖拽 / 编辑 / 自定义 / …

【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练

一、介绍 玉米病害识别系统&#xff0c;本系统使用Python作为主要开发语言&#xff0c;通过收集了8种常见的玉米叶部病害图片数据集&#xff08;‘矮花叶病’, ‘健康’, ‘灰斑病一般’, ‘灰斑病严重’, ‘锈病一般’, ‘锈病严重’, ‘叶斑病一般’, ‘叶斑病严重’&#x…

使用JMeter进行Spring Boot接口的压力测试

使用 Apache JMeter 对接口进行压力测试是一个相对简单的过程。以下是详细的步骤&#xff0c;包括安装、配置和执行测试计划。 1. 下载和安装 JMeter 下载 JMeter 从 JMeter 官方网站https://jmeter.apache.org/download_jmeter.cgi 下载最新版本的 JMeter。 解压缩 将下载的 …

【AIGC】ChatGPT与人类理解力的共鸣:人机交互中的心智理论(ToM)探索

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;心智理论(Theory of Mind,ToM)心智理论在心理学与神经科学中的重要性心智理论对理解同理心、道德判断和社交技能的重要性结论 &#x1f4af;乌得勒支大学研究对ChatGPT-4…

基于python+dj+mysql的音乐推荐系统网页设计

音乐网站开发 如果你在学Python&#xff0c;需相关的【配套资料工具】作为研究[doge][脱单doge] 可以后台✉私信up主&#xff0c;发送&#x1f449;关键词【音乐】 本章以音乐网站项目为例&#xff0c;介绍Django在实际项目开发中的应用&#xff0c;该网站共分为6个功能模块分…

使用开源的 Vue 移动端表单设计器创建表单

FcDesigner Vant 版是一款基于 Vue3.0 的移动端低代码可视化表单设计器工具&#xff0c;通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单&#xff0c;提高开发者对表单的开发效率&#xff0c;节省开发者的时间。 源码下载 | 演示地址 | 帮助文档 本项目采用 Vue3.0 和 …

Elasticsearch基本使用及介绍

Elasticsearch 1. 关于各种数据库的使用 关于MySQL&#xff1a;是关系型数据库&#xff0c;能清楚的表示数据之间的关系&#xff0c;并且&#xff0c;是基于磁盘存储的&#xff0c;可以使用相对较低的成本存储大量的数据 关于Redis&#xff1a;是基于K-V结构的在内存中读写数…