数据结构——lesson13排序之计数排序

💞💞 前言

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:数据结构学习笔记 、排序算法合集
💥对于数据结构顺序表、链表、堆以及排序有疑问的都可以在上面数据结构专栏和排序合集专栏进行学习哦~ 有问题可以写在评论区或者私信我哦~

前面我们学习过七种排序——直接插入排序、希尔排序、直接选择排序、堆排序、冒泡排序、快速排序和归并排序,它们都是通过两数之间进行比较来排序的,今天我们就来学习非比较排序中的计数排序🥳🥳🥳

1.计数排序

基本思想

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

我们这里利用malloc开辟一个数组来统计相同元素出现的次数,用该数字下标表示相同元素,下标对应的值来统计次数
图示如下:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
void CountSort(int* a, int n)
{//开辟数组int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}//将tmp数组的值初始化为0for (int i = 0; i < n; i++){tmp[i] = 0;}//遍历afor (int i = 0; i < n; i++){//tmp下标对应值要++tmp[a[i]]++;}//拷贝回元素组aint j = 0;//记录a下标for (int i = 0; i < n; i++){while (tmp[i]--){a[j++] = i;}}free(tmp);
}
int main()
{int a[] = { 1,3,3,9,7,5,8,7,6 };printf("排序前:");for (int i = 0; i < 9; i++){printf("%d ", a[i]);}printf("\n");CountSort(a, 9);printf("排序后:");for (int i = 0; i < 9; i++){printf("%d ", a[i]);}printf("\n");return 0;
}

结果如下:
在这里插入图片描述

🥲我们仔细观察发现我们开辟tmp数组的大小是n:
int* tmp = (int*)malloc(sizeof(int) * n);
而数组a里面有九个数,也就是tmp大小为9,下标最大也就是8,那么当a中出现比8大的数9时应该怎么计数呢?就不可以计数了,所以出错了;
✨✨那么我们应该开辟多大的数组呢?应该根据什么来开辟才可以呢?
根据a数组最大最小值之差来开辟好像可以,a数组之间的范围就可以作为判断标准;但是这次我们得考虑得全面一点,如果a数组是这样得:a[] = {45,43,36,50,49,44,47}这些呢?那我们岂不是要开辟50个int大小的数组才可以有这么大的下标,如果是考虑范围就是最大50-最小36 = 14,更不可以了;
✨✨解决办法
利用相对值,还是开辟最大-最小的范围大小数组,然后最后拷贝数据的时候让下标+最小的数即可:
代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
void CountSort(int* a, int n)
{//求a数组最大最小差的范围int small = a[0];int big = a[0];for (int i = 1; i < n; i++){//求最大值if (a[i] > big){big = a[i];}//求最小值if (a[i] < small){small = a[i];}}//范围int gap = big - small;//比如0~4,差就是4,但是对应开辟的大小得是5,0~4有五个数//开辟数组int* tmp = (int*)malloc(sizeof(int) * (gap+1));if (tmp == NULL){perror("malloc fail");return;}//将tmp数组的值初始化为0for (int i = 0; i < gap+1; i++){tmp[i] = 0;}//遍历afor (int i = 0; i < n; i++){//tmp下标(a数组对应值-small)对应值要++tmp[a[i]-small]++;}//拷贝回元素组a,记得+samllint j = 0;//记录a下标for (int i = 0; i < gap+1; i++){while (tmp[i]--){a[j++] = i + small;}}free(tmp);
}
int main()
{int a[] = { 1,3,3,9,7,5,8,7,6 };printf("排序前:");for (int i = 0; i < 9; i++){printf("%d ", a[i]);}printf("\n");CountSort(a, 9);printf("排序后:");for (int i = 0; i < 9; i++){printf("%d ", a[i]);}printf("\n");return 0;
}

结果如下:
在这里插入图片描述
当int a[] = {45,43,36,50,49,44,47}时结果如下:
在这里插入图片描述
可以发现,计数排序成功啦~🥳🥳🥳

2.计数排序复杂度分析

2.1空间复杂度

我们根据上述代码实现可以知道计数排序开辟了大小为gap的数组,而gap对应的是最大与最小值的差也就是范围,所以其空间复杂度应该为O(gap);

2.2时间复杂度

时间复杂度:
①求数组a最大最小值时遍历了一遍数组a,次数为n;
②初始化tmp数组为0时遍历了数组tmp,次数为gap;
③统计下标出现次数时遍历数组a,次数为n;
④拷贝回原数组时,遍历了数组tmp,次数为gap;
所以其时间复杂度应该是n+gap+n+gap,简化为O(n+gap);

3.计数排序缺陷分析

前面我们学习的七大排序,时间复杂度最好也要O(n*logn);
而计数排序时间复杂度却可以达到O(n);
俗话说金无足赤,人无完人;计数排序达到这么好的时间复杂度其对应的缺陷也是非常明显的:
💥 缺陷1:依赖数据范围,适用于范围集中的数组
💥 缺陷2:只能用于整形(因为使用数组下标来统计)
所以计数排序使用的条件是非常苛刻的

4.结语

计数排序的关键在于理解并运用它的思想, 以上就是计数排序的介绍与实现啦~,完结撒花 ~🥳🥳🎉🎉🎉

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

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

相关文章

Java 中的单例模式

引言&#xff1a; 在 Java 编程中&#xff0c;单例模式是一种常见的设计模式&#xff0c;它保证一个类只能创建一个实例&#xff0c;并提供一个全局访问点。单例模式在很多场景下都非常有用&#xff0c;比如线程池、日志系统、数据库连接池等。本文将详细介绍 Java 中单例模式的…

操作教程|在MeterSphere中通过SSH登录服务器的两种方法

MeterSphere开源持续测试平台拥有非常强大的插件集成机制&#xff0c;用户可以通过插件实现平台能力的拓展&#xff0c;借助插件或脚本实现多种功能。在测试过程中&#xff0c;测试人员有时需要通过SSH协议登录至服务器&#xff0c;以获取某些配置文件和日志文件&#xff0c;或…

知乎:多云架构下大模型训练,如何保障存储稳定性?

知乎&#xff0c;中文互联网领域领先的问答社区和原创内容平台&#xff0c;2011 年 1 月正式上线&#xff0c;月活跃用户超过 1 亿。平台的搜索和推荐服务得益于先进的 AI 算法&#xff0c;数百名算法工程师基于数据平台和机器学习平台进行海量数据处理和算法训练任务。 为了提…

在 Linux中解压,压缩命令详解

在 Linux中解压&#xff0c;压缩命令详解 在 Linux中解压&#xff0c;压缩命令详解 &#x1f427;&#x1f4bb;摘要引言正文内容解压命令详解1. 解压 .zip 文件unzip 命令 2. 解压 .tar.gz、.tar.bz2、.tar.xz 文件tar 命令 3. 解压其他格式的压缩文件gzip 命令bzip2 命令 压…

哥本哈根Major后steam搬砖该何去何从?

都在问我哥本哈根major比赛过后市场会不会崩盘呢&#xff1f;说实话&#xff0c;我是不喜欢预测市场的&#xff0c;其实是没那个本事而已。若真有这个预测市场走势的本事&#xff0c;我还用坐在这里每天苦哈哈的搬砖吗&#xff1f;我直接干囤卡囤号的倒卖生意岂不早发财了&…

宝塔面板与1Panel的详细对比分析

在当今的服务器管理领域&#xff0c;宝塔面板和1Panel都是备受欢迎的管理工具。它们各自具有独特的特点和优势&#xff0c;同时也存在一些局限性。本文将从多个维度对比这两款产品&#xff0c;帮助用户根据自身需求做出更合适的选择。 宝塔面板 优点 易用性&#xff1a;宝塔…

九州金榜|孩子厌学应该怎么引导?

孩子厌学&#xff0c;这是许多家长都可能面临的问题。对于这个问题&#xff0c;我们首先要明白&#xff0c;厌学并非孩子的错&#xff0c;而是他们在成长过程中所遇到的一种困境。那么&#xff0c;作为家长&#xff0c;我们应该如何引导他们走出这个困境呢&#xff1f;下面九州…

深入浅出:探索Hadoop生态系统的核心组件与技术架构

目录 前言 HDFS Yarn Hive HBase Spark及Spark Streaming 书本与课程推荐 关于作者&#xff1a; 推荐理由&#xff1a; 作者直播推荐&#xff1a; 前言 进入大数据阶段就意味着 进入NoSQL阶段&#xff0c;更多的是面向OLAP场景&#xff0c;即数据仓库、BI应用等。 …

【博弈论——2探究纳什均衡】

1.纳什均衡 纳什均衡&#xff08;Nash Equilibrium&#xff09;&#xff0c;由美国数学家约翰纳什&#xff08;John Nash&#xff09;提出&#xff0c;是博弈论中的一个重要概念&#xff0c;用来描述在一个非合作博弈中&#xff0c;各个参与者在考虑了其他所有参与者策略的前提…

分享 | 顶刊高质量论文插图配色(含RGB值及16进制HEX码)(第三期)

第三期顶刊绘图配色分享来啦&#xff01;这一期做的细心了一点&#xff0c;把双色配色、三色配色、四色配色、多色配色分开展示&#xff0c;大家用起来会更方便一点&#xff1a; 这次还是用之前写了一个多小时的提取论文图片颜色并得出RGB值和16进制码并标注在原图的代码&…

探索c++:string常用接口 迷雾

个人主页&#xff1a;日刷百题 系列专栏&#xff1a;〖C/C小游戏〗〖Linux〗〖数据结构〗 〖C语言〗 &#x1f30e;欢迎各位→点赞&#x1f44d;收藏⭐️留言&#x1f4dd; ​ ​ 一、string类 这里我们对string类进行一个简单的总结&#xff1a; string是表示字符串的字…

矩阵间关系的建立

参考文献 2-D Compressive Sensing-Based Visually Secure Multilevel Image Encryption Scheme 加密整体流程如下: 我们关注左上角这一部分: 如何在两个图像之间构建关系,当然是借助第3个矩阵。 A. Establish Relationships Between Different Images 简单说明如下: …

R语言 | 上下双向柱状图

1. 效果图 2. 代码 # 生成测试数据 difdata.frame(labelspaste0("pathway", 1:3),upc(30,15,1),downc(10,20,40) ) rownames(dif)dif$labels dif#变形 difreshape2::melt(dif) dif# 绘图 ggplot(dif, aes(xlabels, yifelse(variable"up", value, -value), …

react 面试题(2024 最新版)

1. 对 React 的理解、特性 React 是靠数据驱动视图改变的一种框架&#xff0c;它的核心驱动方法就是用其提供的 setState 方法设置 state 中的数据从而驱动存放在内存中的虚拟 DOM 树的更新 更新方法就是通过 React 的 Diff 算法比较旧虚拟 DOM 树和新虚拟 DOM 树之间的 Chan…

单例设计模式(3)

单例模式&#xff08;3&#xff09; 实现集群环境下的分布式单例类 如何理解单例模式中的唯一性&#xff1f; 单例模式创建的对象是进程唯一的。以springboot应用程序为例&#xff0c;他是一个进程&#xff0c;可能包含多个线程&#xff0c;单例代表在这个进程的某个类是唯一…

ROS 2边学边练(6)-- 何为参数(parameters)

概念 这一知识点&#xff0c;应该很好理解&#xff0c;参数就是节点的属性&#xff0c;比如猫科动物&#xff0c;它所拥有的属性&#xff08;参数&#xff09;有胡子、能伸缩的爪子、随光线缩放自如的瞳孔、夜视能力、优秀的弹跳力、萌等等。ROS节点中参数支持的数据类型有整型…

Springboot中的三层架构

我们在进行前后端交互的时候&#xff0c;会分为数据访问&#xff0c;业务逻辑&#xff0c;接受请求并响应数据三个操作&#xff0c;这三部分其实是可以拆分的&#xff0c;让他们解耦&#xff0c;否则代码复用性差并且不易维护&#xff0c;所以诞生了三层架构——1.Dao(数据访问…

VuePress基于 Vite 和 Vue 构建优秀框架

VitePress 是一个静态站点生成器 (SSG)&#xff0c;专为构建快速、以内容为中心的站点而设计。简而言之&#xff0c;VitePress 获取用 Markdown 编写的内容&#xff0c;对其应用主题&#xff0c;并生成可以轻松部署到任何地方的静态 HTML 页面。 VitePress 附带一个用于技术文档…

Redis 常见数据结构及命令

目录 一.Redis常见的数据结构 二.Redis数据结构对应的命令 1.String类型 2.Hash类型 3.List类型 4.Set类型 5.Sorted Set类型 一.Redis常见的数据结构 Redis支持多种数据结构&#xff0c;包括字符串&#xff08;string&#xff09;、哈希&#xff08;hash&#xff09;、…