排序算法对比

1 对比总览

排序算法 核心思想 最好时间复杂度 最坏时间复杂度 平均时间复杂度 空间复杂度 稳定性
插入排序 将待排序元素插入到已有序序列的合适位置 O(n) O(n²) O(n²) O(1) ✅ 稳定
折半插入排序 用折半查找优化插入位置的查找过程 O(n log n) O(n²) O(n²) O(1) ✅ 稳定
希尔排序 分组插入排序,逐步缩小增量 O(n) O(n²) O(n^1.3~n²) O(1) ❌ 不稳定
冒泡排序 相邻元素两两比较,将较大元素逐步"冒泡"到末尾 O(n) O(n²) O(n²) O(1) ✅ 稳定
快速排序 选取基准,分治递归地将序列分为小于和大于基准的两部分 O(n log n) O(n²) O(n log n) O(log n)~O(n) ❌ 不稳定
简单选择排序 每趟选择未排序部分的最小元素放到已排序末尾 O(n²) O(n²) O(n²) O(1) ❌ 不稳定
堆排序 利用堆这种数据结构,不断取出堆顶元素重建堆 O(n log n) O(n log n) O(n log n) O(1) ❌ 不稳定
归并排序 将序列不断二分,对子序列排序后合并 O(n log n) O(n log n) O(n log n) O(n) ✅ 稳定
基数排序 按位(个/十/百位)依次进行分配和收集 O(d·(n+k)) O(d·(n+k)) O(d·(n+k)) O(n+k) ✅ 稳定

注:基数排序中,d 为最大位数,k 为基数(如十进制 k=10)。


2 详细说明

2.1 插入排序

  • 核心思想:将数组分为已排序和未排序两部分,每次从未排序部分取出第一个元素,在已排序部分从后往前依次比较,找到合适位置插入。

  • 适用场景:数据量小(n < 50)或数据基本有序时效率很高。

  • 特点:实现简单,稳定,在接近有序时性能接近 O(n)。

2.2 折半插入排序

  • 核心思想:在插入排序的基础上,利用折半查找(二分查找)在已排序序列中快速定位插入位置,减少比较次数。

  • 特点:相比直接插入排序减少了比较次数,但移动次数不变,整体时间复杂度仍为 O(n²)。

2.3 希尔排序

  • 核心思想:将序列按一定增量分组,对每组进行插入排序;逐步减小增量,当增量为 1 时整个序列基本有序,最后做一次完整插入排序。

  • 增量序列:常见的有 Hibbard 增量(2^k-1)、Sedgewick 增量等,不同增量序列影响时间复杂度。

  • 特点:第一个突破 O(n²) 的排序算法,是插入排序的改进版。

2.4 冒泡排序

  • 核心思想:从前往后依次比较相邻元素,若逆序则交换,每趟将当前未排序部分的最大元素"冒泡"到末尾。

  • 优化方案:设置标志位,若一趟遍历没有发生交换说明已有序,可提前结束。

  • 特点:简单直观,速度较慢,适合教学场景。

2.5 快速排序

  • 核心思想:选择一个基准元素(pivot),将序列分成两部分------小于等于基准的在左边,大于基准的在右边,然后递归地对左右两部分排序。

  • 最坏情况:每次选择的基准恰好是最大或最小元素,退化为 O(n²);可通过随机选取基准或三数取中法优化。

  • 特点 :实际应用中最快的排序算法之一,C 标准库的 qsort 即采用此算法。

2.6 简单选择排序

  • 核心思想:每趟在未排序部分中找到最小(或最大)元素,将其与未排序部分的第一个元素交换。

  • 特点:比较次数始终为 O(n²),与初始序列无关;但移动次数较少。

2.7 堆排序

  • 核心思想:将序列构建成一个大顶堆(或小顶堆),每次取出堆顶元素(最大值或最小值),将堆尾元素移到堆顶后调整堆,重复 n-1 次。

  • 特点:始终保持在 O(n log n) 的时间复杂度,不受初始序列影响;但不稳定。

2.8 归并排序

  • 核心思想:采用分治策略,将序列递归地二分至单个元素,然后逐层合并两个有序子序列。

  • 实现方式:分为自上而下的递归实现和自下而上的迭代实现。

  • 特点:稳定排序,效率稳定在 O(n log n),但需要 O(n) 的额外空间。

2.9 基数排序

  • 核心思想:不直接比较元素大小,而是按位数(个位、十位、百位...)依次进行分配(入桶)和收集(出桶)。

  • 实现方式

    • LSD(Least Significant Digit):从最低位开始排序

    • MSD(Most Significant Digit):从最高位开始排序

  • 特点:非比较排序,适用于整数或固定长度字符串,时间复杂度为线性。

相关推荐
凯瑟琳.奥古斯特41 分钟前
K次取反最大化数组和解法(力扣1005)
开发语言·c++·算法·leetcode·职场和发展
Jerry1 小时前
LeetCode 203. 移除链表元素
算法
地平线开发者1 小时前
征程 6 | 工具链 QAT ObserverBase 源码解析
算法
C语言小火车2 小时前
C++ 快速排序(Quick Sort)深度精讲:分治思想、Lomuto 分区法及三数取中优化,面试手撕必会
c语言·开发语言·c++·面试·排序算法·快速排序
地平线开发者2 小时前
【地平线 征程 6 工具链进阶教程】QAT 训练常见问题和排查
算法
地平线开发者2 小时前
征程 6 | 直方图量化配置与校准实例
算法
地平线开发者2 小时前
征程 6E/M Matrix 开发评板使用系列(一):开箱与点亮
算法·自动驾驶
Jerry3 小时前
LeetCode 59. 螺旋矩阵 II
算法
tachibana23 小时前
hot100 回文链表(234)
java·网络·数据结构·leetcode·链表