稳定排序 (Stable Sort)

排序算法的一种特性:相等元素的相对顺序在排序后保持不变。

定义

稳定排序(Stable Sort) 是指:如果两个元素比较相等(或关键字相同),那么在排序前和排序后,这两个元素的相对位置保持不变。

例如:对 (value, originalIndex) 对进行排序,初始为 [(5,0), (2,1), (5,2), (1,3)],稳定排序后结果为 [(1,3), (2,1), (5,0), (5,2)],两个值为 5 的元素保持了原有的相对顺序(index 0 在 index 2 前面)。

核心特性

特性 说明
稳定性 相等元素保持原有相对顺序
适用场景 需要保持原始顺序的多关键字排序
实现难度 部分算法天然稳定,部分需要额外处理

稳定 vs 不稳定排序

排序算法 是否稳定 说明
冒泡排序 ✅ 稳定 相邻交换,相等时不交换
插入排序 ✅ 稳定 从后向前插入,相等时停止
归并排序 ✅ 稳定 合并时相等取左半部分元素
计数排序 ✅ 可稳定 使用前缀和+从后向前遍历可保证稳定
基数排序 ✅ 稳定 每一位的排序必须使用稳定排序
选择排序 ❌ 不稳定 跨位置交换可能破坏顺序
快速排序 ❌ 不稳定 分区操作可能改变相等元素顺序
堆排序 ❌ 不稳定 堆调整可能改变相等元素顺序
希尔排序 ❌ 不稳定 增量分组可能跨位置移动

为什么稳定性重要

  1. 多关键字排序:先按主键排序,再按次键排序,需要次键排序是稳定的
  2. 保持原始顺序:某些应用场景需要保留数据的原始顺序信息
  3. 基数排序的基础:基数排序依赖每一位的稳定排序

如何实现稳定排序

计数排序的稳定版本

关键点:使用前缀和 + 从后向前遍历

// 稳定计数排序的核心步骤
// 1. 计算前缀和
for (int i = 1; i < count.length; i++) {
    count[i] += count[i - 1];
}
// 2. 从后向前遍历原数组(保证稳定性)
for (int i = nums.length - 1; i >= 0; i--) {
    int num = nums[i];
    result[--count[num - min]] = num;
}

应用场景

  • 基数排序:必须每一位都使用稳定排序
  • 数据库排序:ORDER BY 多个字段时,需要稳定排序
  • 对象多关键字排序:先按年龄排序,再按姓名排序

经典算法

相关概念


Interactive Graph