排序算法-计数排序

news2024/10/6 14:33:53

一、计数排序

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

      如果数组中有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]]+=1
    print(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_arrs

if __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=4
    print(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_arrs

if __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.coloradmin.cn/o/1627420.html

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

相关文章

API和微服务设计的优化方式有哪些?

在构建响应迅速、用户体验良好的应用程序中&#xff0c;API性能的优化至关重要。在构建高性能的API时&#xff0c;采取综合策略是至关重要的。通过采用一系列策略&#xff0c;我们可以确保API在处理请求时高效运行&#xff0c;提供流畅的服务。 一、API和微服务设计的优化可以…

Linux系统安全及应用(1)

目录 一.账号安全控制 系统账号清理 二.密码安全控制 密码安全控制 三.命令历史限制 命令历史限制 四.限制su切换用户 1&#xff09;将信任的用户加入到wheel组中 2&#xff09;修改su的PAM认证配置文件 ​编辑五.PAM认证的构成 六.使用sudo机制提升权限…

机器人系统ros2-开发实践03-监听节点的参数变化(C++)

背景&#xff1a; 通常&#xff0c;节点需要响应其自身参数或另一个节点参数的更改。 ParameterEventHandler 类可以轻松侦听参数更改&#xff0c;以便您的代码可以响应它们。本教程将向您展示如何使用 ParameterEventHandler 类的 C 版本来监视节点自身参数的更改以及另一个节…

深入了解Semaphore、CountDownLatch等实用工具的用法

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…

Android使用ProtoBuf 适配 gradle7.5 gradle8.0

ProtoBuf 适配 Gradle7.5 gradle-wrapper.properties 配置 distributionUrlhttps\://services.gradle.org/distributions/gradle-7.5-bin.zipProject&#xff1a;build.gradle: plugins {id com.android.application version 7.4.2 apply falseid com.android.library versio…

【智能算法】囊状虫群算法(TSA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;S Kaur等人受到囊状虫群自然行为启发&#xff0c;提出了囊状虫群算法&#xff08;Tunicate Swarm Algorithm, TSA&#xff09;。 2.算法原理 2.1算法思想 TSA模拟了囊状虫群在导…

2分钟自己写小游戏:使用js和css编写石头剪刀布小游戏、扫雷小游戏、五子棋小游戏。新手老手毕业论文都能用。

系列文章目录 【复制就能用1】2分钟玩转轮播图,unslider的详细用法 【复制就能用2】css实现转动的大风车&#xff0c;效果很不错。 【复制就能用3】2分钟自己写小游戏&#xff1a;剪刀石头布小游戏、扫雷游戏、五子棋小游戏 【复制就能用4】2024最新智慧医疗智慧医院大数据…

【介绍下OneFlow概念清单】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

61、回溯-分割回文串

思路&#xff1a; 还是全排列的思路&#xff0c;列出每一种组合&#xff0c;然后验证是否是回文&#xff0c;如果是子串放入path中&#xff0c;在验证其他元素是否也是回文。代码如下&#xff1a; class Solution {// 主方法&#xff0c;用于接收一个字符串s并返回所有可能的…

【GO】命令行解析 os 与 flag

目录 OS解析命令 简单用法 进阶用法 flag命令解析 基础实例 1. 自定义数据类型 2. 创建多个 FlagSet 3. 整合环境变量和配置文件 os与flag 关键点解析 程序的作用 示例命令行调用 在 Go 语言中&#xff0c;命令行解析是一项基本且常用的功能&#xff0c;它允许开发者…

玄子Share-Shell编程之条件语句

玄子Share-Shell编程之条件语句 条件测试操作 test命令 测试表达式是否成立&#xff0c;若成立返回0&#xff0c;否则返回其他数值 格式1&#xff1a;test 条件表达式 格式2&#xff1a;[ 条件表达式 ] # 至少应有一个空格文件测试 [ 操作符 文件或目录 ][rootlocal…

[Algorithm][模拟][替换所有问号][提莫攻击][N字形变换][外观数列][数青蛙] + 模拟原理详细讲解

目录 0.原理讲解1.替换所有的问号1.题目链接2.代码实现 2.提莫攻击1.题目链接2.算法原理详解3.代码实现 3.N 字形变换1.题目链接2.算法原理详解3.代码实现 4.外观数列1.题目链接2.算法原理详解3.代码实现 5.数青蛙1.题目链接2.算法原理详解3.代码实现 0.原理讲解 模拟&#xf…

实现SpringMVC底层机制(一)

文章目录 1.环境配置1.创建maven项目2.创建文件目录3.导入jar包 2.开发核心控制器文件目录1.流程图2.编写核心控制器SunDispatcherServlet.java3.类路径下编写spring配置文件sunspringmvc.xml4.配置中央控制器web.xml5.配置tomcat&#xff0c;完成测试1.配置发布方式2.配置热加…

Vue入门篇:生命周期,钩子函数,工程化开发Vue(脚手架安装),组件化开发(全局注册,局部注册)

目录 1.Vue生命周期和生命周期的四个阶段2.Vue生命周期函数&#xff08;钩子函数)3.工程化开发&脚手架Vue CLI1.在powershell管理员权限下打开命令行安装脚手架&#xff1a;2.查看vue版本&#xff1a;3.创建项目架子4.运行项目 4.组件化开发&根组件1.App.vue文件&#…

JavaSE字节缓冲流

欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 博客特色&#xff1a; 在我的博客中&a…

解决minIO 文件上传回显报 403 问题

一、问题描述&#xff1a; minIO 上传文件回显时 提示 403 Forbidden 二、问题原因&#xff1a; minIO 中文件相对应的 buckets 权限问题造成 三、解决办法&#xff1a; 进入 minIO 控制台&#xff0c;将 buckets 中 access Policy 改为 public

监听器模式(三)

一、介绍 监听器模式是一种软件设计模式&#xff0c;在对象的状态发生改变时&#xff0c;允许依赖它的其他对象获得通知。在Java中&#xff0c;可以使用接口和回调机制来实现监听器模式。 二、代码实例 1、事件Event类 package com.xu.demo.listener;// 事件类 public class…

go设计模式之抽象工厂模式

抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 工厂方法模式通过引入工厂等级结构&#xff0c;解决了简单工厂模式中工厂类职责太重的问题&#xff0c;但由于工厂方法模式中的每个工厂只生产一类产品&#xff0c;可能会导致…

【禅道客户案例】同方智慧能源数智化转型新实践 禅道助力前行

同方智慧能源是同方股份有限公司的骨干企业。依托中核集团、清华大学的科技优势&#xff0c;坚持技术和资源双核驱动&#xff0c;基于30多年行业积淀&#xff0c;面向建筑、交通、工业、北方供热、数据中心等主要用能场景提供设计咨询、产品技术、投资建设、运营服务&#xff0…

每天一题crypto(8)---RSA(相邻素数)

题目&#xff1a; p getPrime(512) q gmpy2.next_prime(p) from Crypto.Util.number import * import gmpy2 flag bNSSCTF{******}p getPrime(512) q gmpy2.next_prime(p) n p*q e 65537 phi (p-1)*(q-1)m bytes_to_long(flag)c pow(m, e, n)print(fn {n}) print(f…