8.计数排序

8.1 算法思想

计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),当o(k)< o(nlogn)时快于任何比较排序算法。这是一种牺牲空间换取时间的做法,而且当O(k)>O(nlog(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(nlog(n)), 如归并排序,堆排序)。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

计数排序的基本思想是对于给定的输入序列中的每一个元素x,确定该序列中值小于x的元素的个数(此处并非比较各元素的大小,而是通过对元素值的计数和计数值的累加来确定)。一旦有了这个信息,就可以将x直接存放到最终的输出序列的正确位置上。

计数排序只需遍历一次数据,在计数数组中记录,输出计数数组中有记录的下标,时间复杂度为O(n+k)。
这种算法同时也有额外空间开销计数数组和结果数组,空间复杂度为o(n+k)

8.2 算法过程

  1. 找出待排序的数组中最大和最小的元素;
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;(由于这个原因,要排序的数必须在大于等于0,且由于时间复杂度的问题,数组元素的上限也有一定的限制,否则,时间复杂度不如比较类排序。)
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1.

8.2.1 算法举例

以下说明下计数排序的过程。以《算法导论》这本书的一个例子进行说明:
初始化数组: A[2,5,3,0,2,3,0,3]
假设我们已经事先知道A数组的最大值5,排序过程如下:
a)创建一个长度为6的临时存储数组空间C,并将C数组每一个元素初始化为0。
b)统计重复元素的个数。A数组的元素作为数组C的下标,扫描数组A,A数组元素每出现一次,数组C等于该元素的下标位置的元素加一。例如第一次扫描到的是2,则C[2]=0+1=1,…,第五次再次扫描到了2,C[2]=1+1=2,说明这个数组2的个数为2个。C[2,0,2,3,0,1]
c)计算有多少(y)个元素小于或等于数组C的下标。根据计数数组累加得到C[2,2,4,7,7,8] (小于等于0的有2个,小于等于1的有2个,小于等于2的4个,…小于等于5的有8个)
d)倒序扫描数组A的元素x,依次将元素放置于输出序列res[y]位置,y为小于或者等于这个元素的个数,同时临时数组C[x]=C[x]-1;重复这个过程直至扫描到数组A的首位元素。res[0,0,2,2,3,3,3,5] 因为倒叙遍历原数组,不会改变原来相等元素的相对位置,所以这是稳定的
简而言之就是先统计出数组A元素x小于或等于自身的元素个数y,将x放置于res[y]处,y-1,接着重复这个过程。

简而言之

以[5,3,6,6]数组为例,小于等于5的元素个数为2,小于等于3的元素个数为1,小于等于6的元素个数为4。res = [0,0,0,0],从后往前遍历原数组,6,小于等于6的元素个数为4,最后一个6,放在res[4-1]的位置,这是在剩下的元素中,小于等于6的个数为4-1=3;在继续遍历,6,小于等于6的元素个数为3,放在res[3-1]的位置。再继续遍历,3,这时候小于等于3的元素个数为1,不变,放在res[1-1]的位置;5,小于等于5的元素个数为2,放在res[2-1]的位置。

8.3 python代码

def countingSort(numList):n = len(numList)if n == 0 or n == 1:return numListmaxVal = max(numList)countArr = [0 for i in range(maxVal+1)]for i in numList:countArr[i] += 1for i in range(1,len(countArr)):countArr[i] += countArr[i-1]res = [0 for i in range(n)]for i in range(n-1,-1,-1):res[countArr[numList[i]]-1] = numList[i]countArr[numList[i]] -= 1  # 必须要减1,由于待排序元素在res中的位置是由计数数组的值来决定的。# 当遍历了元素x之后,小于x的元素不会受影响,大于x的元素不会受影响,# 只有等于x的元素会受影响,在往res中压的时候,要比x的位置往前移动一位,# 因此需要将计数数组中的下标为x的值减1,使得下次在遍历到x的时候,# 压入的位置在前一个x的位置之前return resnumlist=[5,8,9,3,2,5,1,6,8]
print(countingSort(numlist))
# 输出结果为:[1, 2, 3, 5, 5, 6, 8, 8, 9]

计数排序(python)相关推荐

  1. 计数排序和桶排序——python和javascript实现

    计数排序 python版 不稳定计数排序 # 不稳定计数排序 def count_sort(arr):max,min = findMaxAndMin(arr)space = max - mincoun ...

  2. 计数排序、桶排序和基数排序的运算性能对比及总结区别(附python代码)

    首先证明一波排序算法的运算性能,如下图.对于50万个数据的无序列表,时间复杂度为的桶排序和计数排序明显比复杂度为的归并排序和快速排序性能好至少一个数量级. 1. 计数排序  1.1 基本原理:首先确定 ...

  3. 计数排序与桶排序python实现

    计数排序与桶排序python实现 计数排序 计数排序原理: 找到给定序列的最小值与最大值 创建一个长度为最大值-最小值+1的数组,初始化都为0 然后遍历原序列,并为数组中索引为当前值-最小值的值+1 ...

  4. Python实现计数排序

    Python实现计数排序 一.计数排序简介 计数排序(Counting Sort)是一种不比较数据大小的排序算法,是一种牺牲空间换取时间的排序算法. 计数排序适合数据量大且数据范围小的数据排序,如对人 ...

  5. python 替换array中的值_Python实现计数排序

    一.计数排序简介 计数排序(Counting Sort)是一种不比较数据大小的排序算法,是一种牺牲空间换取时间的排序算法.计数排序适合数据量大且数据范围小的数据排序,如对人的年龄进行排序,对考试成绩进 ...

  6. 十大经典排序算法(图解与代码)——冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序(Python and Java)

    排序 重新排列表中的元素,使表中的元素按照关键字递增或者递减 内部排序: 指在排序期间,元素全部存放在内存中的排序 外部排序: 指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断 ...

  7. 计数排序之python

    计数排序( Count sort) 一个不需要比较的,类似于桶排序的线性时间排序算法.该算法是对已知数量范围的数组进行排序.其时间复杂度为O(n),适用于小范围集合或重复元素多的排序.计数排序是用来排 ...

  8. 计数排序之python 实现源码

    old = [2, 5, 3, 0, 2, 3, 0, 3] new = [0, 0, 0, 0, 0, 0] for i in range(len(old)):new[old[i]] = new[o ...

  9. 排序算法:计数排序(Python)

    思路:计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中.作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数. 一图解百惑,上图!  话不多说,上代码! def ...

最新文章

  1. kerberos java实现,基于kerberos实现jaas登录
  2. Linux-Shell 快捷键
  3. Proteus仿真STM32F103R6微控制器的EXTI
  4. 软件质量保证与测试——Smoke Test
  5. 1-第一个pyqt5程序
  6. LeetCode 1392. 最长快乐前缀(KMP)
  7. java dumpstack_Java获取执行进程的dump文件及获取Java stack
  8. flink Datastream组装
  9. 页面的主题标记--body
  10. rabbitmq消费者获取消息慢_RabbitMQ:快速生产者和慢速消费者
  11. C语言实现TCP服务端
  12. OWASP Web Testing Environment (WTE) 安装和使用
  13. oracle数据库管理和日常维护,oracle数据库管理与维护
  14. WPF界面框架的设计
  15. gnu开源代码_GNU Health扩展了对Raspberry Pi的支持,Megadeth的吉他手使用了开源原则,以及更多的开源新闻。...
  16. python课程作业-贪吃蛇
  17. 使用POI提取Word文件的内容(纯文本、带html格式)
  18. 银行储蓄系统 类图 顺序图 E_R图 功能结构图 数据流图 系统流图 逻辑结构设计 关系模式 数据关系表
  19. Java程序在结构上的特点_下面关于JavaApplication程序结构特点描述中,错误的是()...
  20. (精华)2020年10月7日 高并发高可用 Redis实现异步架构

热门文章

  1. 2021-2027中国轮径测量仪市场现状及未来发展趋势
  2. 软件工程应用于实践:AJ-Report项目 源码分析(7)
  3. SpaceX拟建海上平台“浮动太空港” 未来可展开超音速全球“点对点”旅行
  4. mysql undo001_MySQL之UNDO及MVCC、崩溃恢复
  5. lazarus linux,简单三步开启树莓派Ubuntu+lazarus之旅
  6. Zynq UltraScale + RFSoC ZCU111专栏3-时钟树配置-LMK04208
  7. 生物信息学练习2- Biom-format
  8. 百度飞浆paddle应用之在嵌入式ARM上运行
  9. Maven无法正常通过快照Snapshots下载jar包问题
  10. Unity实现简易打飞碟(Hit UFO)