数据结构——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.hqwc.cn/news/595811.html

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

相关文章

网络网络层之(3)IPv6地址

网络网络层之(3)IPv6协议 Author: Once Day Date: 2024年4月2日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…

11-LINUX--信号

一.信号的基本概念 信号是系统响应某个条件而产生的事件&#xff0c;进程接收到信号会执行相应的操作。 与信号有关的系统调用在“signal.h”头文件中有声明 常见信号的值&#xff0c;及对应的功能说明&#xff1a; 信号的值在系统源码中的定义如下&#xff1a; 1. #define …

docker容器环境安装记录(MAC M1)(完善中)

0、背景 在MAC M1中搭建商城项目环境时&#xff0c;采用docker统一管理开发工具&#xff0c;期间碰到了许多环境安装问题&#xff0c;做个总结。 1、安装redis 在宿主机新建redis.conf文件运行创建容器命令&#xff0c;进行容器创建、端口映射、文件挂载、以指定配置文件启动…

如何备考2024年AMC10:吃透2000-2023年1250道真题(限时免费送)

2024年AMC10美国数学竞赛还有6个多月就要启动了&#xff0c;那么如何在AMC10比赛中取得好成绩呢&#xff1f;一个被实践的方法是&#xff1a;系统研究和吃透AMC10的历年真题。即使不参加AMC10竞赛&#xff0c;掌握了这些知识和解题思路后初中和高中数学会学得比较轻松、游刃有余…

Spatio-Temporal Pivotal Graph Neural Networks for Traffie Flow Forecasting

摘要:交通流量预测是一个经典的时空数据挖掘问题,具有许多实际应用。,最近,针对该问题提出了各种基于图神经网络(GNN)的方法,并取得了令人印象深刻的预测性能。然而,我们认为大多数现有方法忽视了某些节点(称为关键节点)的重要性,这些节点自然地与多个其他节点表现出…

腾讯云服务器99元一年是真的吗?真的,99元服务器申请入口

腾讯云服务器99元一年是真的吗&#xff1f;真的&#xff0c;99元优惠购买入口 txybk.com/go/99 折合每天8元1个月&#xff0c;腾讯云99元服务器配置为2核2G4M带宽&#xff0c;2024年99元服务器配置最新报价为99元一年&#xff0c;续费也是99元&#xff0c;如下图&#xff1a; …

色彩在设计中的重要性

title: 色彩在设计中的重要性 date: 2024/4/6 19:08:21 updated: 2024/4/6 19:08:21 tags: 色彩心理品牌识别用户体验文化差异创意设计视觉传达易读性 色彩是设计中不可或缺的元素&#xff0c;它不仅可以影响人的情绪和心理状态&#xff0c;还可以在品牌识别、用户体验、文化差…

最短路计数

题目描述 给出一个 N 个顶点 M 条边的无向无权图&#xff0c;顶点编号为 1∼N。问从顶点 1 开始&#xff0c;到其他每个点的最短路有几条。 输入描述 第一行包含 2 个正整数 N,M&#xff0c;为图的顶点数与边数。 接下来 M 行&#xff0c;每行两个正整数 x,y&#xff0c;表示…

ELK报错,索引变成只读状态。

问题描述 今天发现当天的索引在ES中并没有创建&#xff0c;logstash中不停的报错&#xff1a; [2021-05-24T05:47:51,904][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 403 ({“type”>“cluster_block_exception”, “reason”&g…

Navicat设置mysql权限

新建用户&#xff1a; 注意&#xff1a;如果不生效执行刷新命令:FLUSH PRIVILEGES; 执行后再重新打开查看&#xff1b; 查询权限命令&#xff1a;1234为新建的用户名&#xff0c;localhost为访问的地址 SHOW GRANTS FOR 1234localhost;如果服务器设置服务器权限后可能会出现权…

基于SpringBoot+Vue小型企业办公动化系统的设计和开发(源码+部署说明+演示视频+源码介绍+lw)

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通…

Ubuntu/Centos文件误删恢复

Linux服务器上的文件存储都承载着大量的重要信息。然而,文件误删、软件故障或恶意攻击等风险总是伴随着我们。当这些不幸发生时,如何有效地恢复数据成为了一个亟待解决的问题。幸运的是,有相关的数据恢复工具,它能够帮助我们解决Linux服务器上的文件误删问题。 注意:该软…