【数据结构】计数排序等排序

📢博客主页:https://blog.csdn.net/2301_779549673
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述

文章目录

  • 📢前言
  • 🏳️‍🌈计数排序
    • ❤️概念
    • 🧡算法思路
    • 💛算法过程
    • 💚算法性能
    • 💙特别说明
  • 🏳️‍🌈基数排序
  • 🏳️‍🌈桶排序
  • 👥总结


📢前言

  • 上一篇博客中详细介绍了六大常用排序
  • 包括选择、插入、冒泡、希尔、快速、堆排序
  • 这次再扩充一个计数排序
  • 并简述一下基数排序和桶排序

🏳️‍🌈计数排序

我们先来看一下计数排序的 g i f gif gif图,简单理解一下
在这里插入图片描述
下面我们来详细的介绍一下这个排序的内容

❤️概念

计数排序是一个非基于比较的排序算法,元素从未排序状态变为已排序状态的过程,是由额外空间的辅助和元素本身的值决定的。该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为 O ( n + k ) Ο(n+k) O(n+k)(其中k是整数的范围),快于任何比较排序算法。

当然这是一种牺牲空间换取时间的做法,而且当 O ( k ) > O ( n l o g n ) O(k) > O(nlogn) O(k)>O(nlogn) 的时候其效率反而不如基于比较的排序,因为基于比较的排序的时间复杂度在理论上的下限是 O ( n l o g n ) O(nlogn) O(nlogn)

🧡算法思路

计数排序对输入的数据有附加的限制条件:

1、输入的线性表的元素属于有限偏序集 S;

2、设输入的线性表的长度为 n,|S|=k(表示集合 S 中元素的总数目为 k),则 k = O ( n ) k=O(n) k=O(n)

在这两个条件下,计数排序的复杂性为 O ( n ) O(n) O(n)

计数排序的基本思想是对于给定的输入序列中的每一个元素 x,确定该序列中值小于 x 的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定。

一旦有了这个信息,就可以将 x 直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有 17 个元素的值小于 x 的值,则 x 可以直接存放在输出序列的第 18 个位置上。

当然,如果有多个元素具有相同的值时,我们不能将这些元素放在输出序列的同一个位置上,因此,上述方案还要作适当的修改。

💛算法过程

  1. 根据待排序集合中最大元素和最小元素的差值范围,申请额外空间
  2. 遍历待排序集合,将每一个元素出现的次数记录到元素值对应的额外空间内;
  3. 对额外空间内数据进行计算,得出每一个元素的正确位置;
  4. 将待排序集合每一个元素移动到计算得出的正确位置上。

💚算法性能

时间复杂度
O(n+k)。

空间复杂度
O(k)。

稳定性
稳定。

//计数排序
void CountSort(int* a, int n)
{//初始化最大值、最小值int max = a[0];int min = a[0];//找到数组中的最大值for (int i = 1; i < n; i++){if (a[i] > max)max = a[i];else if (a[i] < min)min = a[i];}//设置数组范围int range = max - min + 1;//创建动态空间在堆上,等等记得释放int* Count = (int*)calloc(range, sizeof(int));if (Count == NULL){perror("calloc fail");return;}//记录每个数出现的次数for (int i = 0; i < n; i++){Count[a[i] - min]++;}//写入排序好的数组int j = 0;for (int i = 0; i < n; i++){while (Count[i]--){a[j++] = i + min;}}//释放动态开辟空间free(Count);Count = NULL;
}

💙特别说明

虽然计数排序看上去很强大,但是它存在两大局限性

1.当数列最大最小值差距过大时,并不适用于计数排序

比如给定 20 个随机整数,范围在 0 到 1 亿之间,此时如果使用计数排序的话,就需要创建长度为 1 亿的数组,不但严重浪费了空间,而且时间复杂度也随之升高。

2.当数列元素不是整数时,并不适用于计数排序

如果数列中的元素都是小数,比如 3.1415,或是 0.00000001 这样子,则无法创建对应的统计数组,这样显然无法进行计数排序。

正是由于这两大局限性,才使得计数排序不像快速排序、归并排序那样被人们广泛适用。


🏳️‍🌈基数排序

基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。这种排序算法不是基于比较的排序算法,而是基于“分配”与“收集”。它适用于一定范围内的整数排序,且时间复杂度可以达到线性级别。

基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表示字符串(如名字或日期)和特定格式的浮点数,基数排序并不是只能用于整数。这里是使用基数排序对数字进行排序的一个简单介绍。

基数排序按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别比较每个位数来工作,所以最低位(最右边)首先被使用。然后,如果两个数字的最低位相同,则比较它们的下一位。这个过程持续到最高位。
在这里插入图片描述


🏳️‍🌈桶排序

桶排序的思想就是把待排序的数尽量均匀地放到各个桶中,再对各个桶进行局部的排序,最后再按序将各个桶中的数输出,即可得到排好序的数。

  1. 首先确定桶的个数。因为桶排序最好是将数据均匀地分散在各个桶中,那么桶的个数最好是应该根据数据的分散情况来确定。首先找出所有数据中的最大值mx和最小值mn;

  2. 根据mx和mn确定每个桶所装的数据的范围 size,有
    size = (mx - mn) / n + 1,n为数据的个数,需要保证至少有一个桶,故而需要加个1;

  3. 求得了size即知道了每个桶所装数据的范围,还需要计算出所需的桶的个数cnt,有
    cnt = (mx - mn) / size + 1,需要保证每个桶至少要能装1个数,故而需要加个1;

  4. 求得了size和cnt后,即可知第一个桶装的数据范围为 [mn, mn + size),第二个桶为 [mn + size, mn + 2 * size),…,以此类推
    因此步骤2中需要再扫描一遍数组,将待排序的各个数放进对应的桶中。

  5. 对各个桶中的数据进行排序,可以使用其他的排序算法排序,例如快速排序;也可以递归使用桶排序进行排序;

  6. 将各个桶中排好序的数据依次输出,最后得到的数据即为最终有序。

在这里插入图片描述


👥总结


本篇博文对计数排序等做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

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

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

相关文章

Ubuntu系统中创建桌面快捷方式和添加Favorites

一. Ubuntu系统中创建软件的桌面快捷方式 Ubuntu桌面创建某个软件的桌面快捷方式&#xff0c;一个直观的方法。 方法1. 在图像界面下&#xff0c;一层一层地打开文件目录软件快捷方式/usr/share/applications/ 方法2. 或者在终端运行$ nautilus /usr/share/applications/ …

MQ - RabbitMQ、SpringAMQP --学习笔记

什么是MQ&#xff1f; MQ 是消息队列&#xff08;Message Queue&#xff09;的缩写&#xff0c;它是一种应用程序间异步通信的技术。消息队列允许应用程序或服务间通过发送消息来交换数据&#xff0c;而不是直接调用对方&#xff0c;从而实现解耦、异步处理和负载均衡等目的。…

零成本打造精品宣传册

​随着互联网的发展&#xff0c;企业和个人对宣传册的需求日益增长&#xff0c;然而&#xff0c;高质量的宣传册制作往往需要不菲的成本。那么&#xff0c;如何零成本打造精品宣传册呢&#xff1f; 一、明确定位和目标群体 在制作宣传册之前&#xff0c;首先要明确其定位和目标…

qt pro文件常用配置

概述 记录一下常用的项目pro文件的一些常用配置 常用配置 QT core gui concurrent#添加concurrent并行处理模块 CONFIG windeployqt#打包部署&#xff0c;项目->构建步骤->Make参数 添加windeployqt&#xff0c;编译自动打包greaterThan(QT_MAJOR_VERSION, 4):…

Kafka入门到精通(三)-Kafka

Kafka简介 Kafka是由Apache软件基金会开发的一个开源流处理平台&#xff0c;由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c;搜索和其他用户的行动&#xf…

JeecgBoot新建模块

引言 jeecg-boot设置了demo, system等默认模块。在二次开发中&#xff0c;常常需要进行模块扩展。比如新增一个订单模块或支付模块。如何准确的新增模块&#xff0c;在此文进行记录。 步骤 新建模块 在项目点击右键&#xff0c;新建模块。 如下图。 注意&#xff1a;报名需…

鸿蒙NEXT开发知识:工具常用命令—ohpm config

设置ohpm用户级配置项。 命令格式 ohpm config set <key> <value> ohpm config get <key> ohpm config delete <key> ohpm config list 说明 配置文件中信息以键值对<key> <value>形式存在。 功能描述 ohpm 从命令行和 .ohpmrc 文件中…

Linux命令----wc,uniq,sort的用法

1.wc的用法&#xff1a;wc 命令用于计算文件中的行数、单词数和字节数。 常用选项 -l&#xff1a;只显示行数-w&#xff1a;只显示单词数-c&#xff1a;只显示字节数-m&#xff1a;只显示字符数&#xff08;与 -c 类似&#xff0c;但处理多字节字符&#xff09;-L&#xff1a…

day22--77. 组合+216.组合总和III+17.电话号码的字母组合

一、77. 组合 题目链接&#xff1a;https://leetcode.cn/problems/combinations/ 文章讲解&#xff1a;https://programmercarl.com/0077.%E7%BB%84%E5%90%88.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ti4y1L7cv 1.1 初见思路 组合问题用回溯学会使用剪…

SpringBoot:SpringBoot中调用失败如何重试

一、引言 在实际的应用中&#xff0c;我们经常需要调用第三方API来获取数据或执行某些操作。然而&#xff0c;由于网络不稳定、第三方服务异常等原因&#xff0c;API调用可能会失败。为了提高系统的稳定性和可靠性&#xff0c;我们通常会考虑实现重试机制。 Spring Retry为Spri…

基于uni-app与图鸟UI的移动应用模板构建研究

摘要 随着移动互联网技术的迅猛发展&#xff0c;移动端应用已成为企业展示形象、提供服务的重要窗口。本文基于uni-app框架和图鸟UI设计&#xff0c;深入探讨了如何高效构建覆盖多个领域的移动端应用模板。通过对商城、办公、投票、生活服务等多种类型模板的详细介绍&#xff…

Educational Codeforces Round 112 (Rated for Div. 2) C. Coin Rows(构造 + 贪心 + 前缀和)

可以知道爱丽丝的路径是拐两次弯的折线 那么我们知道鲍勃能够选择的位置只有两段黄线中的一段 所以可以求出来第二行的后缀和&#xff0c;然后求出来第一行的前缀行&#xff0c;这样鲍勃在爱丽丝分割之后的情况下就会选择这两者中最大的一段&#xff0c;然而爱丽丝也会阻碍鲍…

Open AI Stream Completion Set Variable Inside Function PHP With Openai-php SDK

题意&#xff1a;使用 OpenAI 的 PHP SDK&#xff08;例如 openai-php&#xff09;来在函数内部设置和完成一个流&#xff08;stream&#xff09;相关的变量 问题背景&#xff1a; How to set variable inside this openai-php sdk function in stream completion ? I am usi…

华为HCIA综合实验(结合前几期所有内容)

第一章 实验目的 &#xff08;1&#xff09;配置Telnet&#xff0c;要求所有网络设备支持远程管理&#xff0c;密码为admin&#xff08;2&#xff09;配置Trunk&#xff0c;交换机之间的链路均为Trunk模式&#xff08;3&#xff09;配置VLAN&#xff0c;在SW2和SW3上创建相关…

Qt6.6编译Qt二维图形编辑器QVGE源码

QVGE是一个开源的多平台QtC编写的图形编辑器&#xff0c;可以用来画网络节点图&#xff0c;或者其他作用。 QVGE可以轻松创建和参数设定的小型到中型图形(1000节点/边缘)&#xff0c;共同的视觉特性的节点和边缘&#xff1a;形状、尺寸、颜色、标签等。定义(用户定义)属性的图表…

深度学习Week18——学习残差网络和ResNet-50算法

文章目录 深度学习Week18——学习残差网络和ResNet-50算法 一、前言 二、我的环境 三、前期工作 1、配置环境 2、导入数据 2.1 加载数据 2.2 配置数据集 2.3 数据可视化 2.4 再次检查数据 四、构建ResNet-50网络模型 五、编译模型 六、训练模型 七、模型评估 八、指定图片预测 …

leetCode.92. 反转链表 II

leetCode.92. 反转链表 II 题目思路 代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode …

【Python数据分析与可视化】:使用【Matplotlib】实现销售数据的全面分析 ——【Matplotlib】数模学习

目录 安装Matplotlib 1.打开PyCharm&#xff1a; 2.打开终端&#xff1a; 3.安装Matplotlib&#xff1a; 4.确认安装&#xff1a; 导入Matplotlib 创建简单的折线图 代码解析&#xff1a; 创建子图 代码解析&#xff1a; 创建柱状图 代码解析&#xff1a; 创建散点…

Vite响应Ajax请求

Vite响应Ajax请求 陈拓 2024/06/20-2024/06/24 1. 概述 http-server、live-server 等常用于本地测试和开发的http服务器不能很好的支持 ES 模块&#xff0c;在测试ES 模块时浏览器控制台经常显示错误&#xff1a; Failed to load module script: Expected a JavaScript modu…

esp8266 GPIO

功能综述 ESP8266 的 16 个通⽤ IO 的管脚位置和名称如下表所示。 管脚功能选择 功能选择寄存器 PERIPHS_IO_MUX_MTDI_U&#xff08;不同的 GPIO&#xff0c;该寄存器不同&#xff09; PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12);PERIPHS_IO_MUX_为前缀。后面的…