数据结构基础知识

排序

参考:https://www.bilibili.com/video/av38482633/?spm_id_from=trigger_reload

目录

排序

插入排序

直接插入排序

折半排序

希尔排序

交换排序

冒泡排序

快速排序

 选择排序

堆排序

流量单位计算

什么是计数排序

复杂度分析:

什么是基数排序?

复杂度分析(原始数列的规模是N,最大最小整数的差值是M)



插入排序

(有序插入,在有序序列中插入一个元素,保持序列有序,有序长度增加)

直接插入排序

——零号位为哨兵,i位要排序,顺序查找j,依次比较哨兵,大则j往后移覆盖,否则原地不动,i赋值j+1(比较后单向移动,不是交换)

 

折半排序

(循环比较mid=(low+height)/ 2  与哨兵位置的大小,如果哨兵小,则到左半区查找,height=mid-1,否则右半区low=mid+1,直至low大于height,确定插入位置,然后将插入位置后面的所有对象都往后移动位置,将哨兵插入height+1)

希尔排序

(算法是一步一步来的,两两对比,相隔n个数据,然后模仿直接插入排序,完事儿后接着下一个数据接着同样的以上来插入排序,最后一个间隔数值一定是1)

交换排序

冒泡排序

(基于简单的交换思想,两两比较,大的沉底,前小后大,需要一个临时空间暂存交换操作中的元素)

如果发现一次排序后没有交换数据,那咋说明前排的数据都是有序的了,不需要再冒泡排序了

快速排序

(改进的交换排序,取中点放捎点,low、hign指针比较捎点大小分为左右区域,之后左右区域递归,不稳定)

 选择排序

简单选择排序(选择未排序里最小的并与第一个进行交换,之后依次步骤一样)

 

 

 

 

堆排序

无序的话就按数组顺序,由根往下排,并从第一个非叶子节点(n/2 | 0)开始堆调整,直至符合堆的定义


流量单位计算

流量单位G,M,K,B,是什么意思?
G, M, K, B, 都是数据或数据流量的单位符号。
其中,B 是字节的符号,字节 是数据或数据流量的基本单位。
它们之间的换算关系是:


什么是计数排序

先考一道算法题:

数组里有20个随机整数,取值范圉从0到10,要求用最快的速度把这20个整数从小到大进行排序。有没有比快速排序 0( nlogn)更快的排序方法呢?有的,就是用计数排序。

让我们先来回顾一下咱们以前所学过的排序算法,无论是冒泡排序,还是快速排序等等,都是基于元素之间的比较来进行排序。有一种特殊的排序算法叫做【计数排序】,这种排序算法不是基于元素比较,而是利用数组下标来确定元素的正确位置。

基于上题中,整数的取值范围只是从0-10之间,让我们根据这个整数取值范围,建立一个长度为11的数组。数组下标从0到10,元素初始值全为0。

假定20个随机整数的值如下

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

如何给这些无序的随机整数排序呢?

非常简单,让我们遍历这个无序的随机数列,每一个整数按照其值对号入座对应数组下标的元素进行加1操作

比如第一个整数是9,那么数组下标为9的元素加1:

第二个整数是3,那么数组下标为3的元素加1:

最终,数列遍历完毕时,数组的状态如下

数组每一个下标位置的值,代表了数列中对应整数出现的次数

有了这个“统计结果”,排序就很简单了。直接遍历数组,输出数组元素的下标值,

元素的值是几,就输出几次

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

显然,这个输出的数列已经是有序的了。

这就是计数排序的基本过程,它适用于一定范围的整数排序。在取值范围不是很大的情况下,它的性能甚至快过那些0(nlogn)的排序。

初步代码如下:

这段代码在一开头补充了一 一个步骤,就是求得数列的最大整数值max。后面创建的统计数组countArray ,长度就是max+1 ,以此保证数组的最后-一个下标是max。

只以数列的最大值来决定统计数组的长度,其实并不严谨。而应该以最大值和最小值的差来作为数组的大小。不然会浪费空间。

我们不再以(输入数列的最大值+1 )作为统计数组的长度,而是以(数列最大值和最小值的差+1 )作为统计数组的长度。同时,数列的最小值作为-一个偏移量,用于统计数组的对号入座。


以这个数列为例,统计数组的长度为99-90+1 = 10 , 偏移量等于数列的最小值90。对于第一个整数95 ,对应的统计数组下标是95-90 = 5 ,如图所示:

此外,朴素版的计数排序只是简单地按照统计数组的下标输出了元素值,并没有真正给原始数列进行排序。

如果是单纯的给整数排序,这样并没有问题。但如果放在现实业务里,比如给学生的考试分数排序,遇到相同的分数就会分不清谁是谁。
 

给定一个学生的成绩表,要求按成绩从低到高排序,如果成绩相同,则遵循原表固有顺序。
那么,当我们填充统计数组以后,我们只知道有两个成绩并列95分的小伙伴,却不知道哪一个是小红,哪一一个是小绿:
我们需要稍微改变之前的逻辑,在填充完统计数组以后,对统计数组做一下变形。

统计数组从第二个元素开始,每一个元素都加上前面所有元素之和。

这样相加的目的,是让统计数组存储的元素值,等于相应整数的最终排序位置。比如下标是9的元素值为5,代表原始数列的整数9,最终的排序是在第5位。

接下来,我们创建输出数组sortedArray,长度和输入数列一致。然后从后向前遍历输入数列:

第一步,我们遍历成绩表最后一行的小绿:

小绿是95分,我们找到countArray下标是5的元素,值是4,代表小绿的成绩排名位置在第4位。(位置下标是3,因为成绩最少的是第一位,而他下标的位置对应就是0)

同时,我们给countArray下标是5的元素值减1,从4变成3,,代表着下次再遇到95分的成绩时,最终排名是第3。

这样一来,同样是95分的小红和小绿就能够清楚地排出顺序了,也正因此,优化版本的计数排序属于稳定排序

复杂度分析:

如果原始数列的规模是N,最大最小整数的差值是M,你说说计数排序的时间复杂度和空间复杂度是多少?
代码第1, 2, 4步都涉及到遍历原始数列,运算量都是N,第3步遍历统计数列,运算量是M,所以总体运算量是3N+M,去掉系数,时间复杂度是0 (N+M)。
至于空间复杂度,如果不考虑结果数组,只考虑统计数组大小的话,空间复杂度是0 (M) 。

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

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

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

2.当数列元素不是整数,并不适用计数排序。

如果数列中的元素都是小数,比如25.213,或是0.00000001这样子,则无法创建对应的统计数组。这样显然无法进行计数排序。

对于这些局限性,另一种线性时间排序算法做出了弥补,这种排序算法叫做[桶排序],我们后续将会讲到。
参考: 什么是计数排序?


什么是基数排序?

让我们接着来看两个特殊的需求:

需求 A,为一组给定的手机号排序:

18914021920

13223132981

13566632981

13660891039

13361323035

........

........

按照计数排序的思路,我们要根据手机号的取值范围,创建一个空数组。

可是,11 位手机号有多少种组合?恐怕要建立一个大得不可想象的数组,才能装下所有可能出现的 11 位手机号!

需求 B,为一组英文单词排序:

banana

apple

orange

peach

cherry

........

........

计数排序适合的场景是对整数做排序,如果遇到英文单词,就无能为力了。

如何有效处理诸如手机号、英文单词等复杂元素的排序呢?仅仅靠一次计数排序很难实现。

这时候,我们不妨把排序工作拆分成多个阶段,每一个阶段只根据一个字符进行计数排序,一共排序 k 轮(k 是元素长度)。

或许这样的描述有些抽象,我们来举一个例子

数组中有若干个字符串元素,每个字符串元素都是由三个英文字母组成:

bda,cfd,qwe,yui,abc,rrr,uee

如何将这些字符串按照字母顺序排序呢?

由于每个字符串的长度是 3 个字符,我们可以把排序工作拆分成 3 轮:

第一轮:按照最低位字符排序。排序过程使用计数排序,把字母的 ascii 码对应到数组下标,第一轮排序结果如下:

第二轮:在第一轮排序结果的基础上,按照第二位字符排序。

需要注意的是,这里使用的计数排序必须是稳定排序,这样才能保证第一轮排出的先后顺序在第二轮还能继续保持。

比如在第一轮排序后,元素 uue 在元素 yui 之前。那么第二轮排序时,两者的第二位字符虽然同样是 u,但先后顺序万万不能变,否则第一轮排序就白做了。

第三轮:在第二轮排序结果的基础上,按照最高位字符排序。

如此一来,这些字符串的顺序就排好了。

像这样把字符串元素按位拆分,每一位进行一次计数排序的算法,就是基数排序(Radix Sort)。

基数排序既可以从高位优先进行排序(Most Significant Digit first,简称MSD),也可以从低位优先进行排序(Least Significant Digit first,简称LSD)。

不过,如果排序的字符串长度不规则呢?这个问题不难解决。我们以最长的字符串为准,其他度不足的字符串,在末尾补0即可。在排序时,我们把字符 0 当做是比 a 更小的字符,排序结果如下:

ape000

apple0

banana

he0000

orange

代码如下:

备注:

ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII到目前为止共定义了128个字符  。

空字符的ASCII码如下:

这段代码基于一个大循环来实现,循环进行 k 次,k 就是数组中最长字符串元素的字符数。

复杂度分析(原始数列的规模是N,最大最小整数的差值是M

原本计数排序的时间复杂度是0 (n+m),而基数排序总共执行了k次计数排序,所以时间复杂度是0 (k (n+m)),其中k是字符串的最大长度, m是字符范围。

至于空间复杂度,由于基数排序的辅助数组是反复重用的,所以基数排序的空间复杂度和计数排序-样,都是0(n+m),其中m是字符的取值范围大小。

参考:什么是基数排序?


 

 

 

 

 

 

 

 

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

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

相关文章

linux中安装软件,查看、卸载已安装软件方法

各种主流Linux发行版都采用了某种形式的包管理系统(PMS)来控制软件和库的安装。 软件包存储在服务器上,可以利用本地Linux系统上的PMS工具通过互联网访问。这些服务器称为仓库。 由于Linux发行版众多,目前还没有统一的PMS标准工具。 这里分别…

html5 --- 使用javascript脚本控制媒体播放

H5中的标签(<audio…/> 和 <video…/>)对于JS中的HTMLAudioElement对象和HTMLVideoElement对象 对象有以下几个方法: play(): 播放 pause(): 暂停播放 load(): 重新装载音频、视频 canPlayType(type): 判断该元素可播放type类型的音频、视频 下面是一个简单的音乐…

css3 --- 使用媒体查询进行响应式布局

css3引入media,可以根据设备特性进行不同的布局, 本文展示的是根据不同屏幕的宽度进行不同的布局,代码如下: <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title> 针…

node项目正常启动后不能访问(防火墙未放行端口)

今天打开个人站点&#xff0c;发现登陆不了&#xff0c;原以为是pm2的问题&#xff0c;先停了pm2用node app.js的方式运行后端代码&#xff0c;项目能正常启动但是依然不能登陆。 1 检查ecs的安全组规则&#xff0c;node项目端口3000、8888是否放行 2 确认node正常运行 输入…

前端知识点整理(三)不定时更新~

目录 一、移动端跨平台开发方案 Hybrid App React Native Weex Flutter PWA &#xff08;Progressive Web App&#xff09; 小程序 Cordova html5 组件和模块的区别 组件化 模块化 前端代码规范 前端工程化理解 网站性能监测与优化策略 1.网络传输性能优化 页…

前端试题(一)

2020-03-28 金卡智能 *1. 脚手架 vue-cli现在用的什么版本&#xff0c;2版本了解多少&#xff0c;2 3有什么区别 绝对路径与相对路径 ./ 当前路径 …/父路径 / 绝对路径 某文件里引用其他路径下的资源&#xff1a; 判断该文件所在文件夹与其他资源路径间的关系。 什么&#…

html5 --- 利用localStorage进行本地存储

首先做一个提交到本地存储的表单及一个用来显示本地localStorage信息的表格…代码如下: <h2> 本地存储用 </h2>标题: <input id"title" name"title" type"text" size"60" style"margin-left:32px;margin-bottom:…

前端试题(二)

1. 数组方法、reduce()的第二个参数 reduce() MDN文档 accumulator 累计器currentValue 当前值currentIndex 当前索引array 数组 在没有初始值的空数组上调用 reduce 将报错&#xff08;如果有initialValue不报错&#xff09;。回调函数第一次执行时&#xff0c;accumulator…

项目中遇到问题的解决方法合集

以下内容主要是为了方便记录自己在工作中遇到的项目问题搜寻到的解决方法&#xff0c;肯定方法不唯一&#xff0c;这里只是给出解决了我的问题的方法&#xff0c;大家走过路过随便瞧瞧较好啦嘻嘻 1、使用vue/cli 4.x 创建vue项目时使用iconfont 图标无法显示——前者版本问题 …

html5 --- IDBDatabase创建对象存储和索引

代码如下: <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><title> CRUD操作 </title><style type"text/css">table{width: 830px;border: 1px …

2019大疆PC软件开发笔试——开关和灯泡两个电路板

题目描述: 小A是一名DIY爱好者&#xff0c;经常制作一些有趣的东西。 今天&#xff0c;小A突然想要来做这样一个东西。小A现在有两块同样大小为nm&#xff0c;有nm块大小为11小电路板拼成的矩形电路板&#xff0c;假设叫做电路板A和电路板B。电路板A上每个小电路板都是一个开关…

2019高校微信小程序开发大赛获奖作品——《brain头脑智序》

目录 前言 交互流程说明图 我的任务 登录授权&#xff08;login&#xff09; 首页&#xff08;tababr分析&#xff09; 房间准备区&#xff08;preparing&#xff09; 便签编辑区 最终方案选择&#xff08;房主权限&#xff09; 会议报告页面&#xff08;report&#…

前端试题(三)

1. js继承的7种方式 回顾&#xff1a; 每个构造函数都有一个原型对象&#xff1b;原型对象都包含一个指向构造函数的指针&#xff1b;实例都包含一个指向原型对象的内部指针&#xff1b;一切皆为对象&#xff0c;只要是对象&#xff0c;就会有 proto 属性&#xff0c;该属性存…

享元模式 - 结构型模式

模式类型&#xff1a; Flyweight 享元模式 - 结构型模式 意图&#xff1a; The intent of this pattern is to use sharing to support a large number of objects that have part of their internal state in common where the other part of state can vary. 运用共享…

前端试题(四)

1. vue过滤器使用场景 2. v-on绑定多个方法 <p v-on"{click:dbClick,mousemove:MouseClick}"></p>一个事件绑定多个函数&#xff1a; <p click"one(),two()">点击</p>3. 在菜单结构不确定时&#xff0c;前端如何动态渲染 树形…

Mysql - 安装与配置

1、下载安装包 > https://www.mysql.com/downloads/ 2、双击安装&#xff0c;点击Install MySQL Products > 3、Skip 打钩&#xff0c;Next下一步 > 4、选择Server only&#xff1a;只选择安装服务端&#xff0c;根据个人喜好更改安装路径和数据保存路径…

廖雪峰git教程学习

廖雪峰git教程 git – Linus在2周内用c写的 1.1 基本概念 版本控制系统&#xff0c;追踪文本文件的改动&#xff0c;文件、视频等二进制文件则不可追踪&#xff08;微软的word也是二进制文件&#xff09;HEAD 指向当前分支&#xff0c;表示当前版本&#xff08;最新的提交&am…

前端后台管理系统梳理

再梳理一遍 一、商品后台管理系统 1. 功能 1.1 服务端情况 开启了CORS跨域支持需要授权的 API &#xff0c;必须在请求头中使用 Authorization 字段提供token 令牌&#xff08;axios拦截器&#xff09;baseUrl&#xff0c;接口地址&#xff1a;http://localhost:8888/api/…

构造器执行顺序

转载于:https://www.cnblogs.com/a6948076/p/8045801.html