排序算法-计数排序

一、计数排序

       这种排序算法 是利用数组下标来确定元素的正确位置的。

      如果数组中有20个随机整数,取值范围为0~10,要求用最快的速度把这20个整数从小到大进行排序。 很大的情况下,它的性能甚至快过那些时间复杂度为O(nlogn)的排序。

    9,3,5,4,9,1,2,7,8,1,3,6,5,3,4,0,10,9,7,9

   考虑到这些整数只能够在0、1、2、3、4、5、6、7、8、9、10这11个数中取值,取值范围有限。可以根据这有限的范围,建立一个长度为11的数组。数组下标从0到10,元素初始值全为0

    下面就开始遍历这个无序的随机数列,每一个整数按照其值对号入座,同时对应数组下标元素进行加1操作。

    根据这个统计结果,排序就很简单了。直接遍历数组,输出数组元素的下标 值,元素的值是几,就输出几次: 0,1,1,2,3,3,3,4,4,5,5,6,7,7,8,9,9,9,9,10

    计数排序的基本过程,它适用于一定范围内的整数排序。在取值范围不是 很大的情况下,它的性能甚至快过那些时间复杂度为O(nlogn)的排序。

def countSort(ll):# 1.得到数列的最大值max=ll[0]for i in range(1,len(ll)):if ll[i]>max:max=ll[i]# print(max)# 2.根据数列最大值确定统计数组大小,并赋值0;arrs=[0]*(max+1)print(arrs)# 3.遍历数列,填充统计数组for i in range(len(arrs)):arrs[ll[i]]+=1print(arrs)# 4.遍历数列sorted_arrs=[]for i in range(len(arrs)):for j in range(0,arrs[i]):# print(i)sorted_arrs.append(i)#返回排序数组return sorted_arrsif __name__ == '__main__':ll=[9,3,5,4,9,1,2,7,8,1,10]print(ll)print(countSort(ll))

 

以上是找数列的最大值来决定统计数组的长度,其实并不严谨 。

如: 96,93,91,94,95,90,99, 93,91,90

这个数列的最大值是99,但最小的整数是90。如果创建长度为100的数组,那么前面从0到89的空间位置就都浪费了!

    很简单,只要不再以输入数列的最大值+1作为统计数组的长度,而是以数列最大值-最小值+1作为统计数组的长度即可。 同时数列的最小值作为一个偏移量,用于计算整数在统计数组中的下标。 

统计出数组的长度:99-90+1=10,偏移量等于数列的最小值90对于第1个整数96,对应的统计数组下标是96-90=6

如下图所示: 同时数列的最小值作为一个偏移量,用于计算整数在统计数组中的下标。 

 如果学生成绩表,要求按成绩从低到高进行排序,如果成绩相同,则遵循原表固有顺序。

 如图所示:

这是变形,其实就是从统计数组的第2个元素开始,每一个元素都加上前面所有元素之和。 

步骤1:遍历成绩表最后一行的小绿同学的成绩。

小绿的成绩是95分,找到count_array下标是5的元素,值是4,代表小绿的成绩排名位置在第4位。 同时,给count_array下标是5的元素值减1,从4变成3,代表下次再遇到95分的成绩时,最终排名是第3。 

 

步骤2:遍历成绩表倒数第二行的小白同学的成绩。 

 

步骤3:遍历成绩表倒数第三行的小红同学的成绩。  

 

重复上面的步骤继续完成! 

'''优化'''
def countSort2(ll):# 1.得到数列的最大值,最小值max=ll[0]min=ll[0]for i in range(1,len(ll)):if ll[i]>max:max=ll[i]if ll[i]<min:min=ll[i]#差值diff=max-min# print(diff)# 2.确定统计数组大小,并赋值0;arrs=[0]*(diff+1)# print(arrs)# 3.遍历数列,填充统计数组for i in range(len(ll)):arrs[ll[i]-min]+=1   #如:95-90=5,94-90=4print(arrs)# 4.统计数组变形,从第二个元素开始,后面的元素等于前面的元素之和for i in range(1,len(ll)):arrs[i]+=arrs[i-1]  #1+2,3+1,4+1...print(arrs)# 5.排序数列sorted_arrs=[0]*len(ll)# 倒序遍历原始数列,从统计数组找到正确位置for i in range(len(ll)-1,-1,-1):sorted_arrs[arrs[ll[i]-min]-1]=ll[i]  #92-90-1=1;1是排序数列下标,再将对应原始数据最后一个赋值到这个下标。arrs[ll[i] - min] -= 1    #arrs[92-90]-1=arrs[2]-1=1# #返回排序数组return sorted_arrsif __name__ == '__main__':ll = [95,94,91,98,99,90,99,93,91,92]print(ll)print(countSort2(ll))

计数排序有它的局限性,主要表现两点:

1、当数列最大和最小值差距过大时,并不适合用计数排序。

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

2、当数列元素不是整数时,也不适合用计数排序。

  如果数列中的元素都是小数,如25.213或0.000001这样的数字,则无法创建对应的统计数组。

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

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

相关文章

牛客NC406 最长山脉【中等 穷举,动态规划 C++/Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/f4e974a50eda429fbf36515a4197b148 思路 参考答案C class Solution {public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*** param nums int整型vect…

数据结构:最小生成树(Prim算法和Kruskal算法)、图的最短路径(Dijkstra算法和Bellman-Ford算法)

什么是最小生成树&#xff1f;Prim算法和Kruskal算法是如何找到最小生成树的&#xff1f; 最小生成树是指在一个连通图中&#xff0c;通过连接所有节点并使得总权重最小的子图。 Prim算法和Kruskal算法是两种常用的算法&#xff0c;用于寻找最小生成树。 Prim算法的步骤如下&…

11.JAVAEE之网络原理1

1.应用层(和程序员接触最密切) 应用程序 在应用层这里,很多时候, 都是程序员"自定义"应用层协议的,(当然,也是有一些现成的应用层协议)&#xff08;这里的自定义协议,其实是非常简单的~~协议 >约定,程序员在代码中规定好,数据如何进行传输) 1.根据需求, 明确要传…

BUUCTF_[BSidesCF 2020]Had a bad day

[BSidesCF 2020]Had a bad day 1.一看题目直接尝试文件包含 2.直接报错&#xff0c;确实是存在文件包含漏洞 http://307b4461-36d6-443f-879a-68803a57f721.node5.buuoj.cn:81/index.php?categoryphp://filter/convert.base64-encode/resourceindex strpos() 函数查找字符串…

debian gnome-desktop GUI(图形用户界面)系统

目录 &#x1f31e;更新 &#x1f3a8;安装 &#x1f34e;分配 &#x1f6cb;️重启 &#x1f511;通过VNC连接 debian gnome-desktop &#x1f31e;更新 sudo apt update sudo apt -y upgrade &#x1f3a8;安装 sudo apt -y install task-gnome-desktop 这个过程比…

微信小程序开发:2.小程序组件

常用的视图容器类组件 View 普通的视图区域类似于div常用来进行布局效果 scroll-view 可以滚动的视图&#xff0c;常用来进行滚动列表区域 swiper and swiper-item 轮播图的容器组件和轮播图的item项目组件 View组件的基本使用 案例1 <view class"container"&…

PyQt5中的QTablewidget

环境 PyQt5 VSCode Qt Designer生成界面 在VSCode的资源管理器中&#xff0c;右键选择 PYQT:New Form&#xff0c;打开Qt Designer 选择新建Dialog without Buttons&#xff0c;点击 创建 在左侧的Item Widgets中将 Table Widget拖入Dialog窗体中。 得到界面 将文件保存…

基于移动端的uniapp城市应急救援求援系统 微信小程序

本毕业设计的内容是设计实现一个基于 uniapp微信小程序的城市应急救援辅助系统。使用微信开发者是以java语言进行开发&#xff0c;MYSQL为数据库开发平台&#xff0c;城市应急救援辅助系统的功能已基本实现&#xff0c;主要包括有用户、完善个人档案、求援信息上报、医院信息、…

让ThreadPoolExecutor无所遁形:Java线程池运行原理详解

ThreadPoolExecutor的核心工作原理 当我们在Java中讨论并发和多线程时&#xff0c;ThreadPoolExecutor 是不可或缺的一个类。在 java.util.concurrent 包下&#xff0c;该类负责管理线程池内的线程&#xff0c;包括线程的创建、执行、管理以及线程池的监控等。理解 ThreadPool…

汽车底盘域的学习笔记

前言&#xff1a;底盘域分为传统车型底盘域和新能源车型底盘域&#xff08;新能源系统又可以分为纯电和混动车型&#xff0c;有时间可以再研究一下&#xff09; 1&#xff1a;传统车型底盘域 细分的话可以分为四个子系统 传动系统 行驶系统 转向系统 制动系统 1.1传动系…

STM32H7 HSE时钟的使用方法介绍

目录 概述 1 STM32H750 HSE时钟介绍 2 使用STM32Cube创建Project 3 认识HSE时钟 3.1 HSE时钟的特性 3.2 HSE的典型应用电路 4 STM32Cube中配置时钟 4.1 时钟需求 4.2 配置参数 4.2.1 使能外围资源 4.2.2 使用STM32Cube注意项 4.2.3 配置参数 5 总结 概述 本文主要…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.3

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…