快速排序的性能和名字一样优秀

前言

上次分享的冒泡排序虽然比较简单、容易理解,但每一次冒泡的过程都需要依次比较相邻的元素,然后交换,可见性能还是有很大的优化空间,只要能减少比较次数,性能自然就上去啦;快速排序便是一个很不错的选择~~~

正文

1.1 快速排序算法思想

快速排序(Quicksort)是对上一次分享的冒泡排序算法的一种改进,主要是减少比较次数,以此来提高排序性能;也属于交换排序的一种。

算法思想

  • 在待排序列表中任取一个元素作为基准值

  • 将剩下的元素和基准值依次比较,小于的放左边,大于的放右边,最后通过一趟排序将待排序列表分为左右两部分,这个过程称为一次“划分”

  • 然后用同样的方法分别在左右两部分中取基准值进行排序,依次递归,直到划分的每部分内只有一个元素或空为止,则排序结束。

1.2 快速排序算法实现与解析

  • 算法实现

    划分代码实现,每一次取对应部分的首位元素作为基准值,然后通过依次比较,将对应数据又在细分为左右两部分,如下实现:

    image-20210506133026759

    使用递归进行划分排序,直到只有一个元素或为空为止:

    image-20210506133313691
  • 运行效果

    image-20210506133449121
  • 步骤解析(升序)

    image-20210506135153320

    上图步骤说明:

    上图演示是针对数组array进行升序排序,第一次以全部数据为一组,low为0,high为5,选择low位元素2为基准值(即第一个元素),开始进行比较:

    第1.1步:由于刚开始选择low位的元素为基准值(可以认为这个位置空了),所以接下来开始从high位开始遍历比较,high位元素3大于2,不用交换位置,high减1,继续比较;

    第1.2步:此时low为0,high为4,high位元素9大于2,不用交换位置,high减1,继续比较;

    第1.3步:此时low为0,high为3,high位元素1小于2,需要将high位元素1放到基准值的左边,则将元素1放到low指向的位置;

    第1.4步:此时low为0,high为3,由于high位已经交换过了(可以认为这个位置空了),所以这次开始到low位进行遍历比较,low位元素是刚交换过来的,所以不用交换位置;low加1继续比较,此时low为1,对应位置的元素5大于基准值2,所以需要将元素5放到基准值的右边,则将元素5放到high指向位置;

    第1.5步:此时low为1,high为3,由于low位已经交换过了(可以认为这个位置空了),所以这次又回到high位进行遍历比较,high位元素是刚交换过来的,所以不用交换位置;high减1继续比较,此时high为2,对应位置元素6大于基准值2,所以不用交换位置,high减1,继续比较;

    第1.6步:此时low为1,high为1,此时代表第一次划分排序完成,则将基准值放到这个位置;最终将原始数据分为左右两部分,左部分只有一个元素1,不用再划分了,右部分有6,5,9,3四个元素,继续对于右部分进行划分

    第2.1步:由于右部分是从索引位2开始,所以此时low为2,high为5,基准值为low为的元素6;

    第2.2步:由于刚开始选择low位的元素为基准值(可以认为这个位置空了),接下来从high为开始遍历比较,high为元素3小于基准元素6,需要将其放到基准元素的左边,则将元素3放到low指向的位置。

    第2.3步:此时low为2,high为5,由于high位已经交换过了(可以认为这个位置空了),所以这次开始到low位进行遍历比较,low位元素是刚交换过来的,所以不用交换位置;low加1继续比较,此时low为3,对应位置的元素5小于6,不需要交换元素,则low加1,继续比较;

    第2.4步:此时low为4,high为5,low位对应的元素9大于基准值6,所以需要将其放到基准元素的右边,则将元素9放到high指向的位置。

    第2.3步:此时low为4,high为5,由于low位已经交换过了(可以认为这个位置空了),所以这次开始到high位进行遍历比较,high位元素是刚交换过来的,所以不用交换位置;high减1继续比较,此时high为4,此时low和high都为4,找到此次划分基准值的位置,则将基准元素6的放到4位置;到这又将原来的右部分6,5,9,3四个元素划分为左右两部分,右边只有一个元素9,不用继续划分;左边有元素3和5,继续划分排序;(这里就不重复演示)

    最终通过递归划分排序的方式,直到每个划分部分内只有一个元素或空为止,即可获得最后的排序结果。

1.3 快速排序算法分析

时间复杂度

从上面解析步骤得知,每一次排序都是只需要处理剩下未排序的元素,每一次排序时间复杂度不会超过O(n),但由于是通过递归进行划分排序,所以快速排序的整体时间复杂度和递归层数有关,即总的时间复杂度为O(n*递归层数)

通过上面演示得知,其实最终将待排序数据划分为一个二叉树结构,在这二叉树的高度就代表递归的层数(后续会专门分享这块内容),如下图:

image-20210506143932543

关于n个元素的二叉树的最小高度为(log2n)+1,最大高度为n,如果待排序数据已经有序或逆序,如果每次都选择每部分的首个元素为基准值,这样就会导二叉树高度增加,即递归深度就会增加;所以快速排序的时间复杂度最好为O(nlog2n),最坏为O(n2)

这样以为快速排序就不行了吗?当然不是,可以随机选一个元素做为基准值,这样不管待排序数据为有序还是逆序,都不会导致递归深度太深。所以最后快速排序的平均时间复杂度为O(nlog2n)

空间复杂度

空间复杂度在每次递归当中,用到的变量都是固定的(pivot,low,high),则最终影响空间复杂度的因素还是递归层数,则快速排序空间复杂度为O(递归层数), 最好为O(log2n),最坏为O(n)。

稳定性

由于是用待排序数据和基准值进行比较,所以最终元素交换位置不是固定的,则不能保证两个相等元素原有顺序不变,则快速排序是不稳定的。如下图:

image-20210506150331140

如果取low位置的元素3作为基准值,最终会和元素2进行交换,最后就不能保证原来相等元素的前后顺序了。

综上所述,快速排序的时间复杂度为O(nlog2n),空间复杂度为O(log2n),是不稳定算法;

总结

快速排序有效的解决了冒泡排序的缺陷,减少了比较次数,提升了排序性能。但当待排序列表为有序或逆序时,如果单纯的取第一个元素或最后一个元素作为基准值,排序性能并没有提升。所以实现排序算法的关键是需要选个好的基准值,比如可以随机选择,也可以定义一个规则选择,看小伙伴的实现方式咯。

感谢小伙伴的:点赞收藏评论,下期继续~~~

一个被程序搞丑的帅小伙,关注"Code综艺圈",跟我一起学~~~

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

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

相关文章

资料分享 | 教程与开发手册资料分享来袭

小编从大学开始,便开启资料收集功能。随着科技时代的不断发展,计算机语言发展进入新的阶段,再加上日常的深入研究,小编收集整理了丰富的计算机语言学习资料,内容涵盖“教程与开发手册”,“js资料”、“PHP编…

备受期待的Python深度学习来了

在这个酣畅淋漓的暑假结束后,深度学习的四大名著之一漂洋过海来见中国的程序员们啦,豆瓣评分9.5分的《Deep Learning with Python》,推出中译版——《Python深度学习》Deep Learning with PythonPython深度学习扫码购买优惠近30元&#xff01…

安装linux6.10 I386系统教程,一看就懂的Centos6.10安装教程

第一步将虚拟机安装完毕后,运行虚拟机进行到这个界面下(虚拟机安装及其配置,详见论坛内的博客分享在这就不在陈述),:出现的是5条英文由上到下以此分别为:1.安装或升级2.基本的显卡驱动来安装系统(在有些操作系统无法识…

计算机是怎么知道两张图片相似的呢?

全世界有3.14 % 的人已经关注了数据与算法之美很多搜索引擎可以用一张图片,搜索互联网上所有与它相似的图片。你输入网片的网址,或者直接上传图片,Google就会找出与其相似的图片。下面这张图片是美国女演员Alyson Hannigan。上传后&#xff0…

WPF实现下拉框带图文和水印

WPF开发者QQ群&#xff1a; 340500857 有小伙伴需要实现ComboBox下拉框带水印&#xff0c;并且选择Item内容后水印默认从中间到顶部。Item需要展示图文&#xff0c;选择后的数据展示图文。欢迎转发、分享、点赞&#xff0c;谢谢大家~。效果如下&#xff1a;一、Xaml代码如下<…

Google第一女神李飞飞,从洗碗工蜕变成为首席科学家

全世界有3.14 % 的人已经关注了数据与算法之美最近这几天&#xff0c;5岁孩子简历事件刷爆了朋友圈。批阅完朋友圈的文章&#xff0c;超模君心好累。别人家的孩子5岁已经每周3篇英语日记&#xff0c;而5岁我却还在玩泥巴&#xff0c;终于明白什么叫输在起跑线上了。即便输在了起…

通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权...

Oauth2授权&#xff0c;熟悉微信开发的同学对这个东西应该不陌生吧。当我们的应用系统需要集成第三方授权时一般都会做oauth集成&#xff0c;今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方服务保护我们的API应用。目录&#xff1a;一、通过Dapr…

宝宝学数学的第一套书,秒杀题海战术!上小学前应该这样学数学!

作为一个小学口心算特好、初高中也特别好的学霸。小木一直很关心孩子们的数学问题。我一直都在探索如何引领孩子走进数学的大门&#xff0c;启发他学数学的兴趣&#xff0c;以及把数学思维应用到生活中&#xff0c;而不仅仅是学会背数、四则运算、乘法口诀。孩子大多在3、4岁开…

使用 Azure Container Registry 储存镜像

Azure Container Registry&#xff08;容器注册表&#xff09;是基于 Docker Registry 2.0规范的托管专用 Docker 注册表服务。可以创建和维护 Azure 容器注册表来存储与管理专用的 Docker 容器映像和相关项目。Azure Container Registry 类似与阿里云的容器镜像服务。提供镜像…

linux级别3怎么配置DNS,Linux下DNS服务器配置详解

6)辅助区域的文件基本和主区域的配置一样&#xff0c;就是不再需要在options块中加allow-transfer {}&#xff1b;&#xff0c;编辑named.rfc1912.zones文件&#xff0c;如下图进行添加&#xff1a;一定要将默认的"allow-update {none;}; "项&#xff0c;即将允许更新…

入门机器学习,这一步必不可少!

AI这个词相信大家都非常熟悉&#xff0c;近几年来人工智能圈子格外热闹&#xff0c;光是AlphoGo就让大家对它刮目相看。今天小天就来跟大家唠一唠如何进军人工智能的第一步——机器学习。在机器学习领域&#xff0c;Python已经成为了主流。一方面因为这门语言简单易上手&#x…

.NET 中的 Worker Service 入门介绍

翻译自 Steve Gordon 2020年3月30日的文章 《WHAT ARE .NET WORKER SERVICES?》 [1]随着 .NET Core 3.0 的发布&#xff0c;ASP.NET 团队引入了一个新的 Worker Service 项目模板&#xff0c;该模板作为 .NET SDK 的一部分发布。在本文中&#xff0c;我将向您介绍这个新模板&a…

为什么前后端分离了,你比从前更痛苦?

你有没有遇到过&#xff1a;前端代码刚写完&#xff0c;后端的接口又变了。接口文档永远都是不对的。测试工作永远只能临近上线才能开始。为什么前后端分离了&#xff0c;你比从前更痛苦&#xff1f;前后端分离早已经不是新闻&#xff0c;当真正分离之后确遇到了更多问题。要想…

响应式设计(Response Web Design)浅谈

响应式Web设计&#xff0c;这个话题可能是当下Web设计领域里讨论和应用比较多的话题了&#xff0c;为什么要响应式Web设计?什么是响应式Web设计? Web发展迅速&#xff0c;各种应用和服务层出不穷&#xff0c;现在打开电脑&#xff0c;可能使用最多的程序应该是浏览器了&#…

现在6岁的小朋友都开始学编程了……

前段时间&#xff0c;朋友跟小木说&#xff1a;现在的小孩什么都要学&#xff0c;以后是不是都要学编程了&#xff1f;小木鄙夷地笑了一下&#xff1a;他们已经学编程了啊&#xff01;朋友表情↓↓↓朋友&#xff1a;纳尼&#xff1f;&#xff1f;&#xff1f;我到大学才接触编…

记一次 .NET 医院CIS系统 内存溢出分析

一&#xff1a;背景 1. 讲故事前几天有位朋友加wx求助说他的程序最近总是出现内存溢出&#xff0c;很崩溃&#xff0c;如下图&#xff1a;和这位朋友聊下来&#xff0c;发现他也是搞医疗的&#xff0c;哈哈&#xff0c;.NET 在医疗方面还是很有市场的????????????&…

丘成桐:完全不懂数学,才会有“数学无用”的说法

全世界有3.14 % 的人已经关注了数据与算法之美▲中国科学院院长白春礼&#xff08;右&#xff09;与数学家丘成桐&#xff08;左&#xff09;为晨兴数学金奖获得者李思&#xff08;中&#xff09;颁奖培养第一流的学生&#xff0c;首先要有对于学问的兴趣&#xff0c;而非奔着考…

动手实现一个适用于.NET Core 的诊断工具

前言大家可能对诊断工具并不陌生&#xff0c;从大名鼎鼎的 dotTrace&#xff0c;到 .NET CLI 推出的一系列的高效诊断组件&#xff08;dotnet trace,dotnet sos,dotnet dump&#xff09;等, 这些工具提升了对程序Debug的能力和效率&#xff0c;可以让开发人员从更高层次的维度来…

android 强制下线功能,Android学习之基础知识八—Android广播机制实践(实现强制下线功能)...

强制下线功能算是比较常见的了&#xff0c;很多的应用程序都具备这个功能&#xff0c;比如你的QQ号在别处登录了&#xff0c;就会将你强制挤下线。实现强制下线功能的思路比较简单&#xff0c;只需要在界面上弹出一个对话框&#xff0c;让用户无法进行任何操作&#xff0c;必须…

USB权限的设置

USB设备给我们日常生活中带了很多的方便&#xff0c;能够在不同的不同的移动设备中传递数据。但也给我们的数据安全带来了隐患&#xff0c;它可以拷贝走我们计算机中很机密的信息&#xff01;通过下面的操作后&#xff0c;将使我们有用的信息增加更大安全性&#xff0c;至小也能…