Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【算法复习3】时间复杂度 O(n) 的排序 桶排序 计数排序基数排序

【算法复习3】时间复杂度 O(n) 的排序 桶排序 计数排序基数排序

作者头像
韩旭051
发布于 2021-04-14 07:10:24
发布于 2021-04-14 07:10:24
2.1K0
举报
文章被收录于专栏:刷题笔记刷题笔记

对要排序的数据要求很苛刻 重点的是掌握这些排序算法的适用场景

【算法复习3】时间复杂度 O[n] 的排序 桶排序 计数排序基数排序

桶排序(Bucket sort)

将要排序的数据分到几个有序的桶里, 每个桶里的数据再单独进行排序。 桶内排完序之后,再把每个桶里的数据按照顺序依次取出, 组成的序列就是有序的了。

时间复杂度O(n)

  1. n个数据分到 m 个桶内,每个桶里就有 k=n/m 个元素。
  2. 每个桶内部使用快速排序,时间复杂度为 O(k * logk)
  3. m 个桶排序的时间复杂度就是 O(m * k * logk)
  4. 当桶的个数 m 接近数据个数 n 时,log(n/m) 就是一个非常小的常量,这个时候桶排序的时间复杂度接近 O(n)
苛刻的数据
  1. 排序的数据需要很容易就能划分成 m 个桶
  2. 每个桶内的数据都排序完之后,桶与桶之间的数据不需要再进行排序。

桶排序比较适合用在外部排序中。 数据存储在外部磁盘中,数据量比较大,内存有限,无法将数据全部加载到内存中。

计数排序(Counting sort)

计数排序其实是桶排序的一种特殊情况 例子 高考的 一分一档

数据先入桶

然后 顺序求和 更新数据

然后借助这个计数数组来确定下标 非常巧妙

计数排序只能用在数据范围不大的场景中,如果数据范围 k 比要排序的数据 n 大很多,就不适合用计数排序了。而且,计数排序只能给非负整数排序,如果要排序的数据是其他类型的,要将其在不改变相对大小的情况下,转化为非负整数

感谢老师画的图

基数排序(Radix sort)

假设要比较两个手机号码 a,b 的大小,如果在前面几位中,a 手机号码已经比 b 手机号码大了,那后面的几位就不用看了 基数排序从后往前排

按照每位来排序的排序算法要是稳定的 如果 不稳定会打乱顺序 之前的工作就无效了 时间复杂度是 O(k*n) K为数据位数

我们可以把所有的单词补齐到相同长度,位数不够的可以在后面补“0”,因为根据ASCII 值,所有字母都大于“0”,所以补“0”不会影响到原有的大小顺序。这样就可以继续用基数排序了。

基数排序对要排序的数据是有要求的,需要可以分割出独立的“位”来比较,而且位之间有递进的关系,如果 a 数据的高位比 b 数据大,那剩下的低位就不用比较了。除此之外,每一位的数据范围不能太大,要可以用线性排序算法来排序,否则,基数排序的时间复杂度就无法做到 O(n) 了。

评论区大佬的总结

总结:桶排序、计数排序、基数排序 一、线性排序算法介绍 1.线性排序算法包括桶排序、计数排序、基数排序。 2.线性排序算法的时间复杂度为O(n)。 3.此3种排序算法都不涉及元素之间的比较操作,是非基于比较的排序算法。 4.对排序数据的要求很苛刻,重点掌握此3种排序算法的适用场景。 二、桶排序(Bucket sort) 1.算法原理: 1)将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行快速排序。 2)桶内排完序之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。 2.使用条件 1)要排序的数据需要很容易就能划分成m个桶,并且桶与桶之间有着天然的大小顺序。 2)数据在各个桶之间分布是均匀的。 3.适用场景 1)桶排序比较适合用在外部排序中。 2)外部排序就是数据存储在外部磁盘且数据量大,但内存有限无法将整个数据全部加载到内存中。 4.应用案例 1)需求描述: 有10GB的订单数据,需按订单金额(假设金额都是正整数)进行排序 但内存有限,仅几百MB 2)解决思路: 扫描一遍文件,看订单金额所处数据范围,比如1元-10万元,那么就分100个桶。 第一个桶存储金额1-1000元之内的订单,第二个桶存1001-2000元之内的订单,依次类推。 每个桶对应一个文件,并按照金额范围的大小顺序编号命名(00,01,02,…,99)。 将100个小文件依次放入内存并用快排排序。 所有文件排好序后,只需按照文件编号从小到大依次读取每个小文件并写到大文件中即可。 3)注意点:若单个文件无法全部载入内存,则针对该文件继续按照前面的思路进行处理即可。 三、计数排序(Counting sort) 1.算法原理 1)计数其实就是桶排序的一种特殊情况。 2)当要排序的n个数据所处范围并不大时,比如最大值为k,则分成k个桶 3)每个桶内的数据值都是相同的,就省掉了桶内排序的时间。 2.代码实现(参见下一条留言) 案例分析: 假设只有8个考生分数在0-5分之间,成绩存于数组A[8] = [2,5,3,0,2,3,0,3]。 使用大小为6的数组C[6]表示桶,下标对应分数,即0,1,2,3,4,5。 C[6]存储的是考生人数,只需遍历一边考生分数,就可以得到C[6] = [2,0,2,3,0,1]。 对C[6]数组顺序求和则C[6]=[2,2,4,7,7,8],c[k]存储的是小于等于分数k的考生个数。 数组R[8] = [0,0,2,2,3,3,3,5]存储考生名次。那么如何得到R[8]的呢? 从后到前依次扫描数组A,比如扫描到3时,可以从数组C中取出下标为3的值7,也就是说,到目前为止,包括自己在内,分数小于等于3的考生有7个,也就是说3是数组R的第7个元素(也就是数组R中下标为6的位置)。当3放入数组R后,小于等于3的元素就剩下6个了,相应的C[3]要减1变成6。 以此类推,当扫描到第二个分数为3的考生时,就会把它放入数组R中第6个元素的位置(也就是下标为5的位置)。当扫描完数组A后,数组R内的数据就是按照分数从小到大排列的了。 3.使用条件 1)只能用在数据范围不大的场景中,若数据范围k比要排序的数据n大很多,就不适合用计数排序; 2)计数排序只能给非负整数排序,其他类型需要在不改变相对大小情况下,转换为非负整数; 3)比如如果考试成绩精确到小数后一位,就需要将所有分数乘以10,转换为整数。 四、基数排序(Radix sort) 1.算法原理(以排序10万个手机号为例来说明) 1)比较两个手机号码a,b的大小,如果在前面几位中a已经比b大了,那后面几位就不用看了。 2)借助稳定排序算法的思想,可以先按照最后一位来排序手机号码,然后再按照倒数第二位来重新排序,以此类推,最后按照第一个位重新排序。 3)经过11次排序后,手机号码就变为有序的了。 4)每次排序有序数据范围较小,可以使用桶排序或计数排序来完成。 2.使用条件 1)要求数据可以分割独立的“位”来比较; 2)位之间由递进关系,如果a数据的高位比b数据大,那么剩下的地位就不用比较了; 3)每一位的数据范围不能太大,要可以用线性排序,否则基数排序的时间复杂度无法做到O(n)。 五、思考 1.如何根据年龄给100万用户数据排序? 2.对D,a,F,B,c,A,z这几个字符串进行排序,要求将其中所有小写字母都排在大写字母前面,但是小写字母内部和大写字母内部不要求有序。比如经过排序后为a,c,z,D,F,B,A,这个如何实现呢?如果字符串中处理大小写,还有数字,将数字放在最前面,又该如何解决呢?

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/03/08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python-排序-有哪些时间复杂度为O(n)的排序算法?
人到中年,容易变得油腻,思想懒惰,身体就容易发胖。为了摆脱中年油腻,不如和我一起学习算法来烧烧脑子,燃烧你的卡路里。
somenzz
2020/12/10
1.6K0
Python-排序-有哪些时间复杂度为O(n)的排序算法?
JavaScript 数据结构与算法之美 - 桶排序、计数排序、基数排序
笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习。
夜尽天明
2019/07/30
7490
极客算法训练笔记(十),十大经典排序之计数排序、基数排序
终于来到了最后两个算法,非比较类的线性时间复杂度算法,计数排序和基数排序。上一篇也提到过,这几种排序算法理解起来都不难,时间、空间复杂度分析起来也很简单,但是对要排序的数据要求很苛刻,上一篇提到的桶排序就是适用于外部排序中,即所谓的外部排序就是数据存储在外部磁盘中,数据量比较大,内存有限,无法将数据全部加载到内存中。
阿甘的码路
2021/01/03
4410
极客算法训练笔记(十),十大经典排序之计数排序、基数排序
排序算法-线性算法(Java语言实现)
上两节中,我带你着重分析了几种常用排序算法的原理、时间复杂度、空间复杂度、稳定性等。今天,我会讲三种时间复杂度是
acc8226
2022/05/17
5040
排序算法-线性算法(Java语言实现)
排序-线性排序,如何做到百万级数据秒级排序,时间复杂度O(n)?
我们经常接触的冒泡排序,快速排序,归并排序等,这些排序时间复杂度大多是n^2或者N(logN),他们都是基于比较的排序(就是排序过程中数据两两做比较),那你有知道和了解几种线性排序的算法吗?他们的时间复杂度都是O(n),下面的几个问题你会了吗?
阿伟
2019/10/29
2.6K0
排序-线性排序,如何做到百万级数据秒级排序,时间复杂度O(n)?
算法之排序(下)
前面两篇文章说了时间复杂度为O(n2)的冒泡排序、插入排序和选择排序;也说了时间复杂度为O(nlogn)的归并排序和快速排序;这次来说一下时间复杂度为O(n)的桶排序、计数排序和基数排序,由于它们的时间复杂度是线性的,所以它们也叫做线性排序(Linear sort),之所以能够做到线性复杂度,是因为它们在排序的时候,不涉及元素之间的比较,同时它们的使用条件也是非常苛刻的。
信安本原
2020/03/08
3560
基数排序原理及实战
我们来看这样一个排序问题。假设我们有 10 万个手机号码,希望将这 10 万个手机号码从小到大排序,你有什么比较快速的排序方法呢?
用户5325874
2020/01/16
4920
基数排序原理及实战
桶排序原理及实现
桶排序、计数排序、基数排序 三种排序算法的时间复杂度是 O(n) 。因为这些排序算法的时间复杂度是线性的,所以我们把这类排序算法叫作线性排序(Linear sort)。之所以能做到线性的时间复杂度,主要原因是,这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作。
用户5325874
2020/01/16
9830
桶排序原理及实现
Go 语言算法之美—线性排序
前面的两篇文章分别讲述了基础的排序算法,以及应用更加广泛的 O(nlogn) 的排序算法,今天再来看看几种特殊的线性排序算法,之所以叫线性,是因为他们的主要思想都不是基于数据比较,而且时间复杂度接近 O(n)。
roseduan
2021/09/15
2490
JavaScript 数据结构与算法之美 - 十大经典排序算法汇总
笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 JavaScript ,旨在入门数据结构与算法和方便以后复习。
夜尽天明
2019/08/01
6010
JavaScript 数据结构与算法之美 - 十大经典排序算法汇总
八十五、再探希尔排序,桶排序,计数排序和基数排序
关于排序,其实还有很多,比如常见的希尔排序,桶排序,计数排序和基数排序,今天一口气把十大排序剩下的全部解决。
润森
2022/08/17
5460
八十五、再探希尔排序,桶排序,计数排序和基数排序
数据结构与算法学习笔记之为用于高考名次排序的排序算法
  在高考结束以后,所有人都在等着成绩,政府部门面对几百万的数据,你知道他们是怎么算名次的么?上一次学到递归排序以及快排,确实,用他们可以实现,可是他们的时间复杂度最低都是O(nlogn)。今天我们来看看有没有更快捷的排序方法?
Dawnzhang
2018/12/05
5460
数据结构与算法学习笔记之为用于高考名次排序的排序算法
基数排序与桶排序,计数排序【详解】
桶排序简单入门篇^-^ 在我们生活的这个世界中到处都是被排序过的东东。站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东东都
Angel_Kitty
2018/04/09
1K0
基数排序与桶排序,计数排序【详解】
算法渣-排序-基数排序
需要注意的是线性排序算法是非基于比较的排序算法,都有使用限制才能达到线性排序的效果
码农戏码
2021/03/23
4860
数据结构与算法面试:基于比较的排序算法时间复杂度最坏情况下是 O(nlogn),请问有没有更快的算法?(提示:计数排序、基数排序)
简介:基于比较的排序算法时间复杂度最坏情况下是 O(nlogn),请问有没有更快的算法?(提示:计数排序、基数排序)
GeekLiHua
2025/01/21
760
七大经典、常用排序算法的原理、Java 实现以及算法分析
大家好,我是多选参数的程序锅,一个正在 neng 操作系统、学数据结构和算法以及 Java 的硬核菜鸡。数据结构和算法是我准备新开的坑,主要是因为自己在这块确实很弱,需要大补(残废了一般)。这个坑以排序为开端,介绍了 7 种最经典、最常用的排序算法,分别是:冒泡排序、插入排序、选择排序、归并排序、快速排序、桶排序、计数排序、基数排序。对应的时间复杂度如下所示:
syy
2020/06/23
7530
传说中线性时间复杂度的排序算法
谈到排序该怎么算,直觉上应该都要元素之间进行比较才能排出顺序,比较是不可或缺的,但偏偏有的排序算法可以不用比较,比如传说中的“睡眠排序”(n个线程同时睡觉,按照醒来的顺序排序)。因此排序算法可以分成基于比较的排序和非比较的排序2大类。
Jean
2019/10/23
1.6K0
传说中线性时间复杂度的排序算法
十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序
这是十大经典排序算法详解的最后一篇了. 还没有看多之前两篇文章的小伙伴可以先去看看之前的两篇文章:
萌萌哒的瓤瓤
2021/02/02
6130
十大经典排序算法详解(三)-堆排序,计数排序,桶排序,基数排序
再谈基数排序-分治思想:对比计数|基数|桶|堆|希尔|快速|归并
基数排序,最先开始以为很复杂,其实就是正对正整数,先按照个位数大小对数组进行排序,再百位、千位、万位……
周陆军博客
2023/06/06
3620
更新!万字长文带你拿下九大排序的原理、Java 实现以及算法分析
大家好,我是多选参数的程序锅,一个正在捣鼓操作系统、学数据结构和算法以及 Java 的失业人员。数据结构和算法我已经学了有一段日子了,最近也开始在刷 LeetCode 上面的题目了,但是自己感觉在算法上还是 0 ,还得猛补啊。
syy
2020/09/10
7480
更新!万字长文带你拿下九大排序的原理、Java 实现以及算法分析
推荐阅读
相关推荐
Python-排序-有哪些时间复杂度为O(n)的排序算法?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档