首页 > 编程语言 >数据结构与算法 --- 如何分析排序算法

数据结构与算法 --- 如何分析排序算法

时间:2023-08-14 10:57:19浏览次数:48  
标签:排序 复杂度 --- 订单 算法 时间 下单 数据结构

引言

排序算法是最基础的算法,对于排序算法,除学习算法原理,代码实现之外,更重要的是学习每个算法的特点,知道在什么场景下选择那种算法。

那一定是选择时间复杂度最低的排序算法就是最优的吗?

可以从以下几个方面分析一下。

排序算法的执行效率

对于排序算法的执行效率,一般从以下几个方面来分析:

  1. 最好时间复杂度,最坏时间复杂度,平均时间复杂度。

    在分析排序算法的时间复杂度时,我们要分别给出最好,最坏,平均情况下的时间复杂度,以及这些不同的复杂度对应的待排序数据的特点。对于排序算法,原始数据的序度(接近有序的程度),对排序的执行时间有很大影响(尤其极端情况)。

  2. 时间复杂度的系数,常数和低阶。

    时间复杂度反映的是算法的执行时间随数据规模n的增长趋势,再用大O表示法表示复杂度的时候,通常会省略掉系数,常数和低阶。但是当数据规模很小的时候,系数,常数和低阶的占比很大,也需要考虑。

  3. 比较次数或交换(或移动)次数。

    常用的排序算法,如冒泡排序、插入排序、选择排序、快速排序和归并排序等,是基于比较的排序算法,这类排序算法的执行过程设计两个操作:比较元素大小和交换(或移动)元素位置。而这两个操作的耗时是不同的,比较元素大小的耗时要少于交换(或移动)元素位置。所以,在对排序算法的执行效率进行精细化分析时,要把比较次数和交换(或移动)次数区分开来统计。

排序算法的内存消耗

算法的内存消耗可以通过空间复杂度来衡量,排序算法也不例外。除空间复杂度分析之外,根据排序算法是否需要额外的非常量级的数据存储空间,可以分为 原地排序算法(在原数据存储空间上完成排序操作)非原地排序算法(需要额外的非常量级的数据存储空间才能完成排序)

特别注意的是,原地排序并不与 \(O(1)\) 空间复杂度划等号。

一个排序算法是原地排序算法,可能它的空间复杂度并不是 \(O(1)\) ,但是,一个排序算法的空间复杂度是 \(O(1)\) ,那么它肯定是原地排序算法。

排序算法的稳定性

对于大部分算法,只分析执行效率和内存消耗就足够了,不过,排序算法还有一个特有的分析维度:稳定性,根据稳定性,可以把排序算法分为稳定排序算法和不稳定排序算法。

如果带排序的数据中存在值相等的元素,经过稳定排序算法排序之后,相等元素之间原有的先后顺序不变。经过不稳定排序算法排序之后,相等元素之间原有的先后顺序可能会被改变。

例如,有这样一组数据:2、5、9、3、8、5,按照从小到大的的排序之后就变成了2、3、5、5、8、9。

其中数据中有两个5,那么当经过某种排序算法排序之后,两个5的前后顺序无变化,则该排序算法为稳定排序算法,反之,两个5的前后顺序发生变化,则为不稳定排序算法。

那么就产生了疑问,两个5不是一样的吗?

实际上,为了简化对算法的讲解,我们一般是用整数或字符串这些基本数据类型的数据做算法对象演示,但是在真正开发过程中,要排序的对象往往是复杂的数据类型“对象”,按照“对象”的某个属性(称为算法的Key值)进行排序。因此,尽管两个对象的Key值相同,但他们并不是相同的对象。

例如:现在要对电商系统中的“订单”排序,订单有两个属性,“下单时间”和“订单金额”,如果有10万条数据,我们按照金额从小到大排序,对于金额相同的订单,则按照下单时间从早到晚排序。在怎么做?

最先想到的处理方法:首先按照金额对订单进行排序,然后遍历排序之后的订单,对于每个金额相同的小区间在按照下单时间排序,这种排序思路理解起来很直接,符合常规思维,但是实现起来很繁琐。

再来看看借助稳定排序算法的处理思路。我们先按照下单时间给订单排序,注意是按照下单时间而不是金额。在排序完成之后,在利用稳定排序算法,按照订单金额重新排序。在两遍排序后,就达到了预期要求,但是可能理解需要仔细琢磨。

稳定排序算法可以保持金额相同的两个对象,在排序之后的前后顺序不变,在第一次排序之后,所有的订单按照下单时间从早到晚排序,在第二次排序中,我们用稳定排序算法按照金额排序,相同金额的订单原有的先后顺序不变,仍然保持按照下单时间从早到晚排序,如下图:

image.png

可以看出第一次按下单时间排序后,金额为23元的三个订单ID按顺序分别是3、1、6,经过第二次排序之后他们的订单ID按顺序依旧是3、1、6。

参考资料

[1] 数据结构与算法之美 / 王争 著. --北京:人民邮电出版社,2021.6

标签:排序,复杂度,---,订单,算法,时间,下单,数据结构
From: https://www.cnblogs.com/pandefu/p/17536266.html

相关文章

  • Linux-wget命令使用及参数详解
    wget简介Linux系统中的wget是一个下载文件的工具,它用在命令行下。对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器。wget支持HTTP,HTTPS和FTP协议,可以使用HTTP代理。所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行。这意......
  • Chameleon算法的C语言实现及代码解析
    Chameleon算法的C语言实现及代码解析在计算机科学领域中,算法的设计和实现是非常重要的。而在大量的算法中,Chameleon算法以其独特的特点和应用广泛受到了研究者们的关注。本文将围绕Chameleon算法的C语言实现及其代码解析展开,通过具体的示例来解释其原理和应用。Chameleon算法的C......
  • JSON WEB TOKEN - 简单的token认证方式 - 告别session和cookie - Java Demo
    JWT简介jwt非常适合前后分离和分布式的应用不必在服务端存储session,本地也不用存储cookie直接存两段信息即可localStorage["jwt"]=jwt;//tokenlocalStorage["name"]=json.name;//token中加密的某个字段,用于后期请求带上校验token是否被改可以把认证......
  • 推荐搜索算法论文速读1
    n-gram模型参考:https://zhuanlan.zhihu.com/p/32829048简介:一个句子或者一个联想词语,可以使用链式规则建模,利用马尔科夫链的假设(当前词语的产生只与前n个词语产生的概率相关)。n-gram中的n指的就是马尔科夫链假设中的长度。定义:一元模型unigrammodel,二元模型bigrammodel,三元......
  • 基于C#的消息处理的应用程序 - 开源研究系列文章
          今天讲讲基于C#里的基于消息处理的应用程序的一个例子。我们知道,Windows操作系统的程序是基于消息处理的。也就是说,程序接收到消息代码定义,然后根据消息代码定义去处理对应的操作。前面有一个博文例子(C#程序的启动显示方案(无窗口进程发送消息)-开源研究系列文......
  • centos安装arp-scan,使用github上的源码安装
    使用github上的源码安装按照以下步骤使用arp-scan的GitHub源码进行安装:安装编译工具和依赖项:打开终端并以root用户或具有sudo权限的用户身份登录。运行以下命令以安装编译工具和必要的依赖项:sudoyuminstallgccmakelibpcap-devel下载源代码:在终端中,使用以下命令......
  • C语言求凸包的算法及实现
    C语言求凸包的算法及实现凸包问题是计算几何中的一个重要问题,它描述了一个点集中最小的凸多边形。在本文中,我们将探讨使用C语言来解决凸包问题的算法及其实现。C语言求凸包的算法及实现凸包算法的关键在于如何确定一个点是否在凸包上。对于一个给定的点集,我们可以选择一点作为......
  • 「Note」数论方向 - 同余相关
    1.扩展欧几里得算法1.1.介绍扩展欧几里得算法用于求\(ax+by=\gcd(a,b)\)的一组特解(整数解)。推导如下:设\(\begin{cases}ax_1+by_1=\gcd(a,b)\\bx_2+(a\modb)y_2=\gcd(b,a\modb)\end{cases}\)由欧几里得算法可知\(\gcd(a,b)=\gcd(b,a\modb)\)。联立有:\[ax_1+by_1=bx......
  • 【LSOIT1】秒速,五厘米 ----题解
    【LSOIT1】秒速,五厘米----题解题目传送门【明里。】【贵树君。】【明年,也能一起看樱花吗?】【昨天,我做了一个梦,在梦里,我们都才十三岁。那是覆盖着厚厚的一层白雪的田园。】【民家的灯火遥不可及,只能看到零星的两点。】很显然,这是一道签到题,出题人非常良心。题目大意:从......
  • 【LSOIT2】言叶之庭 ---题解
    【LSOIT2】言叶之庭---题解题目传送门【你肯定怀疑我有问题吧。】【没有。】【我不介意呀,反正人类,多多少少有点不正常的。】【我知道这不正常,但真的很喜欢设计鞋子,当然,水平还不够。】【不知不觉,我都在期待雨天。晴天里,总觉得被困在孩子气里的世界,焦虑无比。】【在我看来......