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

news/2024/12/2 20:01:51/

💞💞 前言

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.ppmy.cn/news/1408928.html

相关文章

练习 16 Web [极客大挑战 2019]LoveSQL

extractvalue(1,concat(‘~’, (‘your sql’) ) )报错注入&#xff0c;注意爆破字段的时候表名有可能是table_name不是table_schema 有登录输入框 常规尝试一下 常规的万能密码&#xff0c;返回了一个“admin的密码”&#xff1a; Hello admin&#xff01; Your password is…

Vue关键知识点

watch侦听器 Vue.js 中的侦听器&#xff08;Watcher&#xff09;是 Vue提供的一种响应式系统的核心机制之一。 监听数据的变化&#xff0c;并在数据发生变化时执行相应的回调函数。 目的:数据变化能够自动更新到视图中 原理&#xff1a; Vue 的侦听器通过观察对象的属性&#…

探索K-近邻算法(KNN):原理、实践应用与文本分类实战

第一部分&#xff1a;引言与背景 KNN算法在机器学习领域的重要性及其地位 KNN算法作为机器学习中的基石之一&#xff0c;由于其概念直观、易于理解并且不需要复杂的模型训练过程&#xff0c;被广泛应用于多种场景。它在监督学习中占据着特殊的位置&#xff0c;尤其适用于实时…

综测仪E7515B控制方法

实现自动化控制&#xff0c;本次为大家讲解综测仪E7515B的控制逻辑。 新建底层控制逻辑 在文件basis_contorl.py中写入仪器控制底层代码&#xff0c;代码如下&#xff1a; import tkinter.messagebox import pyvisaclass InstrumentControl(object):inst Nonedef __init__(s…

国家开放大学电大《钢结构》形考任务答案

电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题&#xff0c;包含国家开放大学、广东开放大学、超星等等多个平台题库&#xff0c;考试作业必备神器。 公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#x…

大语言模型开发各个阶段的评估方法(未完)

大语言模型开发过程评估 1. 提出问题2. 大语言模型开发过程评估数据评估方法训练数据质量评估评价数据集或者基准的质量评估 模型评估方法评估基座模型评估通用大语言模型评估专用大语言模型 1. 提出问题 场景&#xff1a;我们要设计一个专有领域的大语言模型&#xff0c;设计…

记第一次eudsrc拿到RCE(上)

目录 前言 个人介绍 挖洞公式 漏洞介绍 CLI命令注入介绍 RCE漏洞介绍 漏洞详情 漏洞点1 漏洞点2 修复建议 总结 前言 免责声明 以下漏洞均已经上报漏洞平台。请勿利用文章内的相关技术从事非法测试。若因此产生一切后果与本博客及本人无关。 本来想大学四年都不会…

顺序表相关习题

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &#x1f4a1; 坚持创作博文…