【手撕排序4】计数排序+快速排序(非递归)


> 🍃 本系列包括常见的各种排序算法,如果感兴趣,欢迎订阅🚩
> 🎊个人主页:[小编的个人主页])小编的个人主页
>  🎀   🎉欢迎大家点赞👍收藏⭐文章
> ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍


🐼前言


🌟在上一节我们实现了归并排序,感受到了归并排序的魅力,如果感兴趣的小伙伴,可以阅读我的上一篇文章:>归并排序 这节小编主要分享计数排序和快速排序的非递归版本。

🐼计数排序

🔍计数排序是一种非比较排序,而在我们上述实现的所有排序中,都是比较排序。

其思想是,统计相同元素出现的次数

根据 统计的结果将序列回收到原来的序列中

 ☀️动图解析: 

👀 从上述动图,我们可以看出,需要创建一个计数的数组,那么这个数组需要开辟多大的空间呢?

从上面的案例看到,如果最大值是9,就开辟10个(最大值+1个)空间,因为下标是从0开始的。那如果是{100,101,102,103,104,105}.那需要开辟105+1个空间吗?显示,这会造成空间浪费。如图:

❄️如果我们能求出这组序列的最大值和最小值。那么就可以根据序列的范围(range = max-min+1)向操作系统申请空间,并将count数组中所有元素置为0,刚开始还没有计数。这样用于计数的数组就创建好了。

❄️这样,将原数组所有元素都映射到计数数组中,映射规则是:当前值-这组序列中的最小值。比如{100,101,102,103,104,105}序列。101映射到计数数组下标就是(101-100 = 1),所以在count数组下标为1的位置计数加1。以此类推,将原序列所有元素都映射到计数数组中,正如我们动图所演示。

👀那么想得到排序好的序列该咋办呢?

我们知道,count数组中每个位置下标所对应的值,就是映射过来的该元素对应出现的次数

那么我们还原回去,就需要将count每个位置映射回去(原数组元素=计数数组下标+min),而我们又知道,count数组的值就是原数组出现次数,那计数几次,就映射几次过去。最后,不要忘记释放申请的count数组。

具体代码:

#include<string.h>
//计数排序(非比较排序)
void CountSort(int* arr, int n)
{int min = arr[0], max = arr[0];//找最大最小值for (int i = 1; i < n; i++){if (arr[i] > max){max = arr[i];}if (arr[i] < min){min = arr[i];}}int range = max - min +1;//创建count数组,并初始化为0//写法1//int* count = (int*)calloc(sizeof(int)*range,sizeof(int));//写法2int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail");exit(-1);}memset(count, 0, sizeof(int) * range);//计数for (int i = 0; i < n; i++){count[arr[i] - min]++;}//还原原数组int index = 0;for (int i = 0; i < range; i++){while (count[i]--){arr[index++] = i + min;}}free(count);count = NULL;
}

🐼快速排序(非递归)

🔍在之前,我们实现了快速排序的三种实现方式,今天来完成快速排序的非递归版本。

在快速排序时,需要不断地根据基准值划分左右区间,就像二叉树一样。非递归的快速排序需要用栈来模拟划不断分左右区间这个过程,就像模拟二叉树的实现方式。

如图:

🍃我们用栈来模拟这个过程,先让原序列右下标和左下标入栈(先让右入栈,因为栈先入后出),接着,只要栈不为空,就一次取两个元素,即左下标和右下标。再通过前面找基准值的三种方式,任意一种,找到keyi,此时划分左序列为[left,key-1],右序列[keyi+1,right],只要keyi + 1 < right,keyi-1>left,将右序列先入栈,再将左序列入栈。即入栈顺序:right->keyi+1->keyi-1->left.

具体代码

// 快速排序 非递归实现
void QuickSortNonR(int* arr, int left, int right)
{ST st;StackInit(&st);StackPush(&st,right);StackPush(&st, left);while (!StackEmpty(&st)){//取栈顶两个元素int begin = StackTop(&st);StackPop(&st);int end = StackTop(&st);StackPop(&st);int prev = begin, cur = prev + 1;int keyi = begin;while (cur <= end){if (arr[cur] < arr[keyi] && ++prev != cur){Swap(&arr[cur], &arr[prev]);}cur++;}Swap(&arr[prev], &arr[keyi]);//基准值keyi//左序列begin prev-1//右序列prev+1 endif (prev + 1 < end){StackPush(&st, end);StackPush(&st, prev + 1);}if (begin < prev - 1){StackPush(&st, prev - 1);StackPush(&st, begin);}}STDestory(&st);
}

 🐼排序算法时间复杂度和稳定性

🔍稳定性:排序的稳定性是指在排序过程中,如果存在多个具有相同关键字的记录,这些记录在排序前后的相对顺序保持不变。这意味着在排序操作中,如果两个元素相同,它们在最终结果中的位置应与在原始数据集中的位置相同

我们总结一下各种排序的性能对比:

感谢你看到这里,如果觉得本篇文章对你有帮助,点个赞👍 吧,你的点赞就是我更新的最大动力。⛅️🌈 ☀️

这车好有感觉~

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

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

相关文章

FPGA实现以太网(一)、以太网基础知识

系列文章目录 FPGA实现以太网&#xff08;二&#xff09;、初始化和配置PHY芯片 文章目录 系列文章目录一、以太网简介二、OSI七层模型三、TCP/IP五层模型四、MAC-PHY接口五、MAC帧格式六、IP帧格式6.1 IP首部校验和计算6.2 IP首部校验和校验 七、UDP帧格式7.1 UDP头部校验和…

Linux平台C99与C++11获取系统时间

源码: #include <iostream> #include <chrono> #include <ctime> #include <thread>using namespace std; int main() {cout << "===使用C99方式获取系统时间===" << endl;time_t now = time(nullptr);struct tm *tm_c99 = lo…

QT版发送邮件程序

简单的TCP邮箱程序 **教学与实践目的&#xff1a;**学会网络邮件发送的程序设计技术。 1.SMTP协议 邮件传输协议包括 SMTP&#xff08;简单邮件传输协议&#xff0c;RFC821&#xff09;及其扩充协议 MIME&#xff1b; 邮件接收协议包括 POP3 和功能更强大的 IMAP 协议。 服务…

【学习记录】使用CARLA录制双目摄像头SLAM数据

一、数据录制 数据录制的部分参考了网上的部分代码&#xff0c;代码本身并不复杂&#xff0c;基本都是简单的CARLA语法&#xff0c;关键的一点在于&#xff0c;CARLA内部本身并没有预设的双目摄像头&#xff0c;需要我们添加两个朝向相同的摄像头来组成双目系统&#xff0c;这…

第02章 CentOS基本操作

2.文件基本操作【文件操作&#xff08;一&#xff09;】 目标 理解Linux下路径的表示方法能够使用命令(mkdir和touch)在指定位置创建目录和文件能够使用命令(rm)删除指定的目录和文件能够使用命令(ls)列出目录里的文件能够使用命令(cat,head,tail,less,more)查看文件内容理解标…

【数字图像处理+MATLAB】解决 imshow 函数图像显示亮度异常问题:自动调整亮度范围使图像能正确显示

问题描述 在MATLAB中&#xff0c;使用imshow函数进行图像显示时&#xff0c;图片亮度显示异常。 imshow(im_avg);执行上述代码后&#xff0c;得到的图片亮度异常&#xff0c;如下图所示&#xff1a; 原因分析 在MATLAB中&#xff0c;imshow函数的亮度显示规则是基于图像数据…

探索 Python 的新边疆:sh 库的革命性功能

文章目录 **探索 Python 的新边疆&#xff1a;sh 库的革命性功能**第一部分&#xff1a;背景介绍第二部分&#xff1a;sh 库是什么&#xff1f;第三部分&#xff1a;如何安装 sh 库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 执行 ls 命令2. 使用 grep 搜索文件内容…

外贸管理利器7选,助力高效办公

推荐7款外贸管理软件&#xff0c;包括ZohoBooks、ZohoCRM、富通天下等&#xff0c;各具特色&#xff0c;满足外贸企业不同需求&#xff0c;提高管理效率&#xff0c;助力企业全球化竞争。、 一、Zoho Books Zoho Books是一款外贸财务管理软件&#xff0c;不仅为用户提供了一个…

SQL中的内连接(inner join)、外连接(left|right join、full join)以及on关键字中涉及分区筛选、null解释

一、简介 本篇幅主要介绍了&#xff1a; SQL中内连接&#xff08;inner join&#xff09;、外连接&#xff08;left join、right join、full join&#xff09;的机制;连接关键字on上涉及表分区筛选的物理执行及引擎优化&#xff1b;null在表关联时的情况与执行&#xff1b; …

机器学习(一)——基本概念、模型的评估与选择

目录 1 关于2 概念2.1 基础概念2.2 学习过程2.3 预测与评估2.4 标记与分类2.4.1 标记2.4.2 分类 2.5 回归分析2.6 聚类分析2.7 学习类型2.8 泛化能力2.9 统计学概念 3 模型评估与选择3.1 经验误差与过拟合3.2 评估方法3.2.1 留出法3.2.2 交叉验证法3.2.3 自助法3.2.4 调参与最终…

ssm060基于SSM的高校共享单车管理系统的设计与实现+vue(论文+源码)_kaic

设计题目&#xff1a;高校共享单车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0…

聚观早报 | 比亚迪腾势D9登陆泰国;苹果 iOS 18.2 将发布

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 11月5日消息 比亚迪腾势D9登陆泰国 苹果 iOS 18.2 将发布 真我GT7 Pro防尘防水细节 小米15 Ultra最快明年登场 …

三菱QD77MS定位模块速度更改功能

速度更改功能” 是以任意时机将控制中的速度更改为新指定的速度的功能。更改后的速度直接设置到缓冲存储器中&#xff0c;并根据速度更改指令([cd.15速度更改请求)或者外部指令信号执行速度更改。 但是&#xff0c;机械原点复位的情况下&#xff0c;检测出近点狗 ON 并开始向蠕…

flink 内存配置(二):设置TaskManager内存

flink 内存配置&#xff08;一&#xff09;&#xff1a;设置Flink进程内存 flink 内存配置&#xff08;二&#xff09;&#xff1a;设置TaskManager内存 flink 内存配置&#xff08;三&#xff09;&#xff1a;设置JobManager内存 flink 内存配置&#xff08;四&#xff09;…

线段树专题(1)

线段树 线段树可维护的信息类型 线段树可以维护的信息类型&#xff0c;父范围上的某个信息&#xff0c;可以用O(1)的时间&#xff0c;从子范围的信息加工得到&#xff0c;例如求某个范围的最大最小值&#xff0c;给某个范围每个位置加相同的数字&#xff0c;进行求和。 0到2范…

NoETL自动化指标平台为数据分析提质增效,驱动业务决策

直觉判断往往来源于多年的经验和专业知识&#xff0c;能够在复杂和不确定的环境中快速做出决策反应。但这种方式普遍存在主观偏见&#xff0c;缺乏合理的科学依据&#xff0c;无法全面、客观、精准地评估和识别市场趋势与用户需求&#xff0c;从而造成决策失误&#xff0c;给业…

软考高级架构 - 8.1 - 系统质量属性与架构评估 - 超详细讲解+精简总结

第8章 系统质量属性与架构评估 软件系统属性包括功能属性和质量属性&#xff0c;而软件架构重点关注质量属性。 8.1 软件系统质量属性 8.1.1 概述 软件系统的质量反映了其与需求的一致性&#xff0c;即&#xff1a;软件系统的质量高低取决于它是否能满足用户提出的需求&#…

Jmeter常见的几种报错及解决方案

在性能测试的过程中&#xff0c;使用JMeter进行负载测试是一项常见而重要的任务。然而&#xff0c;测试中常常会遇到各种报错&#xff0c;这些问题可能会影响测试结果的准确性。了解这些错误的原因及解决方案&#xff0c;是每位测试工程师必备的技能 进行Jmeter项目练习的时候…

《JavaEE进阶》----21.<基于Spring图书管理系统②(图书列表+删除图书+更改图书)>

PS&#xff1a; 开闭原则 定义和背景‌ ‌开闭原则&#xff08;Open-Closed Principle, OCP&#xff09;‌&#xff0c;也称为开放封闭原则&#xff0c;是面向对象设计中的一个基本原则。该原则强调软件中的模块、类或函数应该对扩展开放&#xff0c;对修改封闭。这意味着一个软…

仿真APP助力汽车零部件厂商打造核心竞争力

汽车零部件是汽车工业的基石&#xff0c;是构成车辆的基础元素。一辆汽车通常由上万件零部件组成&#xff0c;包括发动机系统、传动系统、制动系统、电子控制系统等&#xff0c;它们共同确保了汽车的安全、可靠性及高效运行。 在汽车产业快速发展的今天&#xff0c;汽车零部件…