冒泡和快速排序的时间复杂度_八大排序算法性能分析及总结

4bf50057686e1a9199e494c9b704c3ad.png

一、排序算法说明

  1. 排序的定义:对一个无序的序列进行排序的过程。
    输入:n个数:a1,a2,a3,…,an。
    输出:n个数的排列:a1,a2,a3,…,an,使得a1<=a2<=a3<=…<=an。
  2. 排序的稳定性:相同值的节点相对位置是否会发生改变。
    稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
    不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面。
  3. 排序的时间复杂度:一个算法执行所耗费的时间,一般在三种情况下考虑:最好情况、最坏情况、平均情况。
  4. 空间复杂度:运行完一个程序所需内存的大小。

二、各种排序算法性能分析

1. 插入排序1.1 直接插入排序
直接插入排序的原理是将未排好序的序列一个个地插入到已排好序的序列中,插入时,需要与已排好序的序列进行多次比较,直到找到合适的位置插入,而原来已排好序的部分节点可能需要进行后移操作,这个过程中需要一个额外的空间保存一个值用于交换节点,所以空间复杂度为O(1)。

时间复杂度
最坏情况:当待排序序列正好为逆序状态,首先遍历整个序列,之后一个个地将待插入元素放在已排序的序列最前面,之后的所有元素都需要向后移动一位,所以比较和移动的时间复杂度都是O(n),再加上遍历整个序列的复杂度,总复杂度为O(n^2)。
最好情况:当待排序序列正好为正序状态,则遍历完整个序列,当插入元素时,只比较一次就够了,所以时间复杂度为O(n)。
平均情况:当被插入的元素放在已排序的序列中间位置时,为平均情况,比较和移动的时间复杂度为O(n/2),所以总的时间复杂度依然为O(n^2)。

稳定性
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

1.2 希尔排序
希尔排序是对直接插入排序的优化,它的原理是加大插入排序中元素的间隔,并在这些有间隔的元素中进行插入排序,从而使数据进行大幅度的移动,当进行过依次排序后,再减小间隔再一次进行插入排序,直到间隔缩小为1。这样做的目的可以使得最后排序时整个序列基本有序,而无需再进行过多的元素比较和移动次数,在这个过程中也只需要一个额外的空间保存一个值用于交换节点,所以空间复杂度为O(1)。

时间复杂度与增量的选取有关,计算起来较为复杂,不再细述。

稳定性
希尔排序是进行多次直接插入排序的算法,由于多次插入排序,虽然每一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。

2. 选择排序2.1 直接选择排序
直接选择排序的原理是在待排序的序列中选取最小(大)的值放在序列的第一个位置。遍历整个序列,首先选取第一位置的值分别与之后所有的值比较,如果后边值更小则与之交换,直到第一轮遍历结束时,序列第一个位置的值就是最小的,接下来继续从第二个、第三个做同样的操作,此过程需要一个额外的空间保存最小值用于交换,所以空间复杂度为O(1)。

时间复杂度
序列无论是正序还是逆序状态,每一轮的最小值需要比较到最后才能确定,所以最坏情况和最好情况下都需要 比较n次,再加上遍历整个序列的O(n),总的复杂度为O(n^2),平均情况的复杂度也是O(n^2)。

稳定性
直接选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。举个例子,序列5 8 5 2 9, 第一遍选择时第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

2.2 堆排序
堆排序是对直接选择排序的改进算法,选择排序的特点在于每次选取最小或最大的值,而选取最大值时的比较次数为复杂度的关键,堆排序采用二叉树的方法存储元素,每个节点都满足父节点的值大于等于子节点的特点,与直接选择排序类似,堆排序需要两个个值的空间来存储临时变量,用于交换节点,一次用于存储子树最大节点用于交换子节点,一次用于存储堆顶的值用于交换最后的节点,所以空间复杂度为O(1)。

采用堆的方式寻找最大值是降低时间复杂度的关键,假设有n个数据,需要n-1次建堆的过程,每次建堆的时间复杂度为log2n,但是无论序列的开始状态如何,都需要对堆进行遍历寻找最大值,所以在最好情况、最坏情况和平均情况下的时间复杂度都是O(nlog2n)。

稳定性
堆排序是利用堆的特点,堆的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n /2-1, n/2-2, …1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是一个稳定的排序算法。

3. 交换排序3.1 冒泡排序
冒泡排序是交换类排序算法的典型实现,它的原理是遍历整个序列,比较前后相邻两个值的大小,如果前边比后边大,则交换它们,直到序列的最后的两个值进行比较,这样最后的值就是最大的,之后再进行第二轮、第三轮遍历,直到剩下序列的最前的值。从实现原理上可以知道,冒泡排序只需要一个值的空间用于交换节点,所以空间复杂度为O(1)。

时间复杂度
最坏情况:序列为逆序状态,则每一轮遍历都需要n次交换位置,所以时间复杂度为O(n^2)。
最好情况:序列为正序状态,每一轮遍历不需要交换位置,所以时间复杂度为O(n)。
平均情况:每一轮遍历需要n/2次交换位置,所以时间复杂度依然为O(n^2)。

稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,不会发生交换。如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,也不会发生交换,所以相同元素的前后顺序并没有改 变,所以冒泡排序是一种稳定排序算法。

3.2 快速排序
快速排序是另一种交换类排序方法,它的原理是选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。首先就地快速排序使用的空间是O(1)的,而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据,每一次都平分数组的情况下空间复杂度为O(logn) ,最差的情况下空间复杂度为O(n)。

时间复杂度
最坏情况:每一次选取的基准元素都是最大或最小的,复杂度为O(n^2)
最好情况:每一次选取的基准元素都能平分整个序列,由于快排涉及到递归调用,所以时间复杂度为O(nlog2n)。
平均情况:平均情况下复杂度也是O(nlog2n)。稳定性
快速排序有两个方向,左边的i下标一直往右走,当a[i]<=a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j]>a[center_index]。如果i和j都走不动了,i<=j, 交换a[i]和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。

4. 归并排序
归并排序先递归的把数组划分为两个子数组,一直递归到数组中只有一个元素,然后再调用函数把两个子数组排好序,因为该函数在递归划分数组时会被压入栈,所以这个函数真正的作用是对两个有序的子数组进行排序。排序函数的步骤,让两个数组的元素进行比较,把大的/小的元素存放到临时数组中,如果有一个数组的元素被取光了,那就直接把另一数组的元素放到临时数组中,然后把临时数组中的元素都复制到实际的数组中。所以 归并的空间复杂度就是那个临时的数组和递归时压入栈的数据占用的空间n + logn,所以空间复杂度为:O(n)。

时间复杂度
归并排序的时间主要花在了划分序列和合并序列上,由于是采用递归的方式进行合并,所以与快速排序类似,树的每层元元素的个数最多是n,也就代表着每层最多进行n次比较,而递归树最多只有log2n层,而且不管元素在什么情况下都要做这些步骤,所以该算法的最优时间复杂度和最差时间复杂度及平均时间复杂度都是一样,都是O( nlogn )。

稳定性
归并排序的原理是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也不会交换,所以不会破坏稳定性。而在短的有序序列合并的过程中,稳定性也没有受到破坏,合并过程中可以保证如果两个当前元素相等时,把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序是稳定的排序算法。

三、各种排序算法性能总结

982c3ac12d8a628483d4f4da553f5bee.png

参考

排序算法之性能分析及总结_Blog-CSDN博客​blog.csdn.net
668105716217d406f74023c2bb6ec944.png
超详细的八大排序算法的各项比较以及各自的特点_柯南的博客-CSDN博客​blog.csdn.net
6a7bca742a0f2529acd39d898865a50b.png

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

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

相关文章

同步android wear音乐,Android Wear首次更新:添加离线音乐 GPS功能等

凤凰科技讯 北京时间10月24日消息&#xff0c;据科技博客TechCrunch报道&#xff0c;Android Wear日前迎来了其发布后的首次大更新。谷歌为这一可穿戴设备的操作系统添加了离线音乐、蓝牙耳机以及GPS定位等功能。此次更新意味着&#xff0c;当你出去慢跑但将智能手表落在家里的…

JAVA入门级教学之(异常的处理try...catch)

* 处理异常的第二种方式&#xff1a;捕捉 try{}catch(){} * * 语法&#xff1a; * try{ * 可能出现异常的代码; * } * catch(异常类型1 变量){ * 处理异常的代码; * } * catch(异常类型2 变量…

docker 挂载目录_Docker容器数据管理

在Docker容器内部创建的文件默认存储在可写的容器层&#xff0c;容易产生几个问题:当容器不存在时&#xff0c;数据文件不能持久化&#xff0c;同时这些数据文件不方便在容器之外被其他进程使用。当容器运行的时候容器可写层严重依赖宿主机&#xff0c;不能轻易移动这些数据文件…

android 获取应用列表,获取全部应用列表

有时需对已安装的应用进行管理 &#xff0c; 这里我简单的写了获取应用程序列表。代码如下&#xff1a;package com.lml.applicationtest;import java.util.List;import android.app.Activity;import android.content.Context;import android.content.pm.PackageInfo;import an…

IndexNotReadyException: Please change caller according to com.intellij.openapi.project.IndexNotReady

打开AS有时会报这个错&#xff0c;之前没怎么在意&#xff0c;因为完全没影响&#xff0c;但是看起来标红就很难受&#xff0c;总觉得认真有强迫症的程序员才是好的程序员&#xff0c;所以特意查了解决办法&#xff0c;也很简单&#xff0c;就点击Files----->Invalidate and…

java数组有跨类建立对象_必会的 55 个 Java 性能优化细节!一网打尽!

程序员的成长之路互联网/程序员/成长/职场 关注阅读本文大概需要 10 分钟。来源&#xff1a;https://yq.aliyun.com/articles/662001在 Java 程序中&#xff0c;性能问题的大部分原因并不在于 Java 语言&#xff0c;而是程序本身。养成良好的编码习惯非常重要&#xff0c;能够显…

android平板截屏方法,Android 各种截屏方法

1 应用内截屏(无SurfaceView, TextureView)boolean cacheEnable captureView.isDrawingCacheEnabled();captureView.setDrawingCacheEnabled(true);captureView.buildDrawingCache();Bitmap bitmap captureView.getDrawingCache();cache[0] Bitmap.createBitmap(bitmap);cap…

android string 去掉斜杠,Android – PATH中的改装和斜杠字符

我正在面临一个与Retrofit的问题,并希望找到一个合适的答案,作为唯一的方式,我可以想到它是相当丑陋和不实际.Retrofit PATH注释在开始时需要一个“/”(你可以从这个从库中提取的代码中读取&#xff1a;/** Loads {link #requestUrl},{link #requestUrlParamNames},and {link #…

新手操作HTML

一、 首先得学会使用HTML5-API手册&#xff0c;因为HTML的属性有很多很多&#xff0c;如果将这些属性全部记下来的话得不偿失&#xff0c;需要花费大量的时间和经历&#xff0c;因此我们需要学会使用这个帮主文档才能全面而深入的了解HTML&#xff1b; 就像你去找对象一样&am…

nginx 判断手机端跳转_nginx基本功能和工作原理

nginx能做什么反向代理正向代理负载均衡HTTP服务器(包含动静分离)反向代理和正向代理1.正向代理简单的说,我是一个用户,我无法直接访问一个网站,但是我能访问一个代理服务器,这个代理服务器能访问那个我不能访问的网站,于是我先连上代理服务器,告诉它我需要那个无法访问网站的内…

Node.js教程-express框架

概述 Express是基于Node.js平台(建立在Node.js内置的http模块上)&#xff0c;快速、开放、极简的Web开发框架。 中文官网 http://www.expressjs.com.cn/。 Github地址&#xff1a;https://github.com/orgs/expressjs。 Express核心特性&#xff1a; 可设置中间件来响应 HTTP…

android开发适配深色模式,手机不支持深色模式,如何用软件解决深色模式的问题?(附有系统全局深色模式实现方法...

本帖最后由 巷子口的你 于 2020-8-8 07:57 编辑1.92允许通过设置为助手应用来饮捷切频深色模式(设置入口一般为系统默认应用-助手和语音输人, MIU需要设置为语音助手)提醒:稳定模式一股不用开启, OPPO等设备开启深色模式后自动关团的才需要开启,据反馈,部分OPPO设备在锁屏后还是…

python猜数字游戏续_python3实现猜数字游戏

本文实例为大家分享了python3实现猜数字游戏的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下 需求目标&#xff1a; 需求:猜数字游戏 1: 开始游戏产生一个1~100随机数 2: 用户输入&#xff0c;游戏根据输入值提示大或者小 3: 用户根据提示继续输入&#xff0c;知道猜…

HTML的script标签

在 HTML 页面中插入一段 JavaScript&#xff1a; 这句话可能大家一开始根本不了解JavaScript&#xff0c;是什么&#xff1f; 在我的了解中JavaScript并不是用java语言开发的&#xff0c;人家用的是c语言和另外一种语言的结合体&#xff0c;就像印度和印度尼西亚根本不是同一…

织梦cms在线生成html,织梦CMS标签生成器

标题 / 关键词 / 描述title / keywords / description{dede:field.title/} - {dede:global.cfg_webname/}获取顶级栏目相关信息gettoptype(me,typename){dede:field.typeid functiongettoptype(me,typename)/}获取上级栏目相关信息getredtype(me,typename){dede:field.typeid f…

tesseract4.0.0 中文语言包_一份TensorFlow2.0中文教程

近两个月&#xff0c;网上已经出现了大量 TensorFlow 2 0 英文教程。在此文章中&#xff0c;本文为大家推荐一个持续更新的中文教程&#xff0c;以便大家学习。来源&#xff1a;机器之心今年 3 月份&#xff0c;谷歌在 Tensorflow Developer Summit 2019 大会上发布 TensorFlow…

HTML的块级元素和行级元素的标签列表

行内元素列表: <a>标签可定义锚点 <abbr>表示一个缩写形式 <acronym>定义只取首字母缩写 <b>字体加粗 <bdo>可覆盖默认的文本方向 <big>大号字体加粗 <br>换行符号 <cite>引用进行定义 <code>定义计算机代码文…

android光传感实现摩斯密码,根据莫尔斯代码 - Android的闪烁闪光。 如何避免ANR次数由于睡觉? (火炬APP)...

所以&#xff0c;我做了一个火把应用...正常火炬功能完全正常&#xff0c;没有任何问题。下面介绍以下功能&#xff0c;可能会导致可能的ANR的说&#xff0c;我想通过闪烁的闪光灯发出SOS信息(莫尔斯电码)。 (其111-000-111)&#xff0c;所以它开 - 开 - 开 - 关 - 关 - 和重复…

mysql select count 5万条数据很慢_mysql亿级数据数据库优化方案测试银行交易流水记录的查询...

点击上方△蓝字关注我们带你征服编程和泡妞两座大山对MySQL的性能和亿级数据的处理方法思考&#xff0c;以及分库分表到底该如何做&#xff0c;在什么场景比较合适&#xff1f;比如银行交易流水记录的查询限盐少许&#xff0c;上实际实验过程&#xff0c;以下是在实验的过程中做…

HTML的引用

<q></q>定义比较短的引用&#xff0c;直接加双引号 <blockquote cite"来源的网址"</blockquote>浏览器用缩进的形式显示该段文本 HTML5强调&#xff1a;语义与现实分离&#xff08;意思是说写好的东西普普通通&#xff0c;但是可以通过另外的…