当前位置: 首页 > news >正文

八大排序算法的比较

以下将从排序思想、算法稳定性、时间复杂度和空间复杂度四个方面对八大排序算法(冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、基数排序)进行详细比较。

1. 冒泡排序

  • 思想:重复走访要排序的数列,一次比较两个相邻元素,如果顺序错误就把它们交换过来,每一轮会将最大(或最小)的元素 “浮” 到数列末尾,直到整个数列有序。
  • 稳定性:稳定。因为只有相邻元素比较且顺序错误时才交换,相等元素不会交换,相对顺序不变。
  • 时间复杂度
    • 最好情况(数列已有序):O(n),只需遍历一次,无元素交换。
    • 最坏和平均情况:O(n^2),需要进行大量比较和交换。
  • 空间复杂度:O(1),只需要常数级额外空间用于交换元素。

2. 选择排序

  • 思想:每一轮从待排序元素中选出最小(或最大)的元素,与待排序序列的第一个元素交换位置,不断缩小待排序序列,直到整个数列有序。
  • 稳定性:不稳定。例如 [5, 8, 5, 2],选最小 2 与第一个 5 交换,两个 5 相对顺序改变。
  • 时间复杂度:无论数列初始状态如何,都需进行n(n - 1)/2次比较,时间复杂度始终为O(n^2) 。
  • 空间复杂度:O(1),只需要常数级额外空间用于交换元素。

3. 插入排序

  • 思想:将未排序数据插入到已排序序列的合适位置。初始时,第一个元素视为已排序,从第二个元素开始,依次将其插入到前面已排序序列的正确位置。
  • 稳定性:稳定。插入过程中,相等元素会插入到相等元素后面,相对顺序不变。
  • 时间复杂度
    • 最好情况(数列已有序):O(n),只需遍历一次,每个元素只需比较一次。
    • 最坏和平均情况:O(n^2),每个元素可能需要移动多个位置。
  • 空间复杂度:O(1),只需要常数级额外空间用于元素移动。

4. 希尔排序

  • 思想:是插入排序的改进版,先将整个待排序的记录序列分割成若干个子序列,分别对这些子序列进行直接插入排序,随着增量逐渐减小,子序列长度增加,整个序列变得越来越接近有序,最后进行一次直接插入排序。
  • 稳定性:不稳定。由于不同子序列的插入操作,可能会改变相等元素的相对顺序。
  • 时间复杂度:与增量序列的选择有关,平均情况约为 O(n^{1.3}) 到 O(n^2) 之间。
  • 空间复杂度:O(1),只需要常数级额外空间用于元素移动。

5. 归并排序

  • 思想:采用分治法,将数列分成两个子数列,分别对两个子数列进行排序,然后将排好序的子数列合并成一个最终的有序数列。不断递归地分割和合并,直到整个数列有序。
  • 稳定性:稳定。在合并过程中,相等元素会按顺序放入合并后的序列,相对顺序不变。
  • 时间复杂度:无论最好、最坏还是平均情况,时间复杂度都是O(nlogn) ,因为每次分割和合并的时间复杂度都是 O(logn)和 O(n)。
  • 空间复杂度:O(n),需要额外的数组空间来合并子序列。

6. 快速排序

  • 思想:同样采用分治法,选择一个基准元素,将数列分为两部分,使得左边部分的元素都小于等于基准元素,右边部分的元素都大于等于基准元素,然后分别对左右两部分递归进行排序。
  • 稳定性:不稳定。在分区过程中,可能会改变相等元素的相对顺序。
  • 时间复杂度
    • 最好和平均情况:O(nlogn),每次分区能均匀分割数列。
    • 最坏情况(数列已有序):O(n^2),每次分区只能将数列分成一个元素和其余元素两部分。
  • 空间复杂度
    • 平均情况:O(logn),递归调用栈的深度为 logn。
    • 最坏情况:O(n),递归调用栈的深度达到 n。

7. 堆排序

  • 思想:利用堆这种数据结构,先将数列构建成一个最大堆(或最小堆),然后将堆顶元素(最大值或最小值)与最后一个元素交换,再调整堆,重复此过程,直到整个数列有序。
  • 稳定性:不稳定。在堆调整和交换过程中,可能会改变相等元素的相对顺序。
  • 时间复杂度:无论最好、最坏还是平均情况,时间复杂度都是O(nlogn) ,因为每次调整堆的时间复杂度为 O(logn),需要进行 n次调整。
  • 空间复杂度:O(1),只需要常数级额外空间用于元素交换。

8. 基数排序

  • 思想:将整数按位数切割成不同的数字,然后按每个位数分别比较。从最低位开始,依次对每一位进行排序,直到最高位,最终得到有序数列。
  • 稳定性:稳定。在按位排序过程中,相等元素会按顺序放入排序结果,相对顺序不变。
  • 时间复杂度:O(d(n+k)),其中 d是最大数字的位数,n是数列元素个数,k是每一位的取值范围(如十进制为 10)。
  • 空间复杂度:O(n+k),需要额外的空间来存储临时数据。
排序算法排序思想稳定性时间复杂度(平均)空间复杂度适用场景
冒泡排序重复走访要排序的数列,交换相邻元素,直到整个数列有序。稳定O(n²)O(1)小规模数据,简单场景
选择排序每一轮选出最小(或最大)元素,与第一个元素交换,直到整个数列有序。不稳定O(n²)O(1)小规模数据
插入排序将未排序数据插入到已排序序列的合适位置,每次插入一个元素直到整个数列有序。稳定O(n²)O(1)部分有序数据,数据量小
希尔排序将数列分割成多个子序列,对每个子序列进行插入排序,逐渐减少间隔,最后进行一次插入排序。不稳定O(n^(3/2))O(1)大规模数据,部分有序数据
归并排序采用分治法将数列分割成子数列,排序并合并子数列,直到整个数列有序。稳定O(n log n)O(n)大规模数据,稳定性要求高
快速排序采用分治法,通过基准元素分割数列,递归对左右部分进行排序。不稳定O(n log n)O(log n)大规模数据,适用于平均情况较好的数据
堆排序利用堆结构调整元素,每次取堆顶元素(最大或最小),再调整堆,直到整个数列有序。不稳定O(n log n)O(1)大规模数据,内存受限
基数排序按位数切割数列,逐位进行排序,从最低位到最高位,最终得到有序数列。稳定O(d(n+k))O(n+k)整数数据,数值范围有限的数据

相关文章:

  • 解锁养生密码,拥抱健康生活
  • 故障诊断 | Matlab实现基于DBO-BP-Bagging多特征分类预测/故障诊断
  • React 源码揭秘 | hooks原理
  • 基于 SpringBoot Vue 的生鲜商城系统设计和实现(源码+文档+部署讲解)
  • 2.3做logstash实验
  • vue2 ruoyi websocket轮询
  • Ansible-03 docker安装-基于centos
  • 使用Python爬虫获取孔夫子旧书网已售商品数据:调用item_search_sold接口
  • SmartMediakit之音视频直播技术的极致体验与广泛应用
  • 安装TortoiseGit时,显示需要安装驱动?!
  • kafka的ACL配置的sasl.kerberos.principal.to.local.rules配置解释
  • JavaScript的BOM编程
  • 前端页面什么是全屏嵌入/什么是局部嵌入
  • 费曼学习法7 - NumPy 数组的 “变形术”:形状变换与索引切片 (基础篇)
  • 当PHP遇上区块链:一场奇妙的技术之旅
  • 基于SSA-KELM-Adaboost(麻雀搜索优化的极限学习机自适应提升算法)的多输入单输出回归预测【MATLAB】
  • 如何用python将pdf转为text并提取其中的图片
  • js基础语法
  • 前端监控与埋点
  • Three.js 入门(辅助、位移、父子关系、缩放旋转、响应式布局)
  • 国家统计局:4月全国城镇调查失业率为5.1%,比上月下降0.1个百分点
  • 美联储计划裁员约10%
  • 李伟任山东省委常委、省纪委书记
  • 土耳其、美国、乌克兰三边会议开始
  • 乌克兰官员与法德英美四国官员举行会谈
  • 2025年“新时代网络文明公益广告”征集展示活动在沪启动