排序要不要稳定?这事儿得看场景

前两天帮朋友写个导出报表的小功能,他顺口问了句:‘这个排序用稳定的吗?’我愣了一下,心想这问题挺小,但真说清楚还真得琢磨琢磨。

啥叫排序稳定?

简单说,就是相等元素的相对顺序在排序后会不会变。比如有两个学生分数都是85分,原来小明在小红前面,排完序如果小明还在小红前面,那就是稳定排序;要是颠倒了,就不稳定。

常见的排序算法里,归并排序是稳定的,快排一般不是。这点差异看起来不起眼,但在某些场合能踩坑。

什么时候非得要稳定?

举个实际例子:公司后台有个订单列表,按状态分组展示,每组内部再按创建时间倒序。你要是用不稳定排序,先按时间排好,再按状态分组的时候,时间顺序可能就乱了。

还有一种情况,前端常遇到——表格多列排序。第一次点“部门”排序,第二次点“薪资”。如果排序不稳定,原本按部门排好的人,一按薪资,部门顺序全打乱了,用户肯定懵。

那是不是所有排序都得稳定?

也不是。如果你只是想把一堆数字从小到大排出来,谁在前谁在后无所谓,那就没必要强求稳定。毕竟稳定排序通常会多花点时间和空间,比如归并排序需要额外数组,快排虽然原地操作快,但牺牲了稳定性。

再比如日志处理,按时间戳排序,同一秒的日志成千上万条。除非你有业务逻辑要求它们保持原始顺序(比如按接收顺序),否则根本不在乎谁先谁后。

代码里怎么选?

大多数语言内置的排序默认是稳定的。Python 的 list.sort() 和 JavaScript 的 Array.prototype.sort() 在现代引擎里基本都稳定。但 C++ 的 std::sort 不保证稳定,要用 std::stable_sort 才行。

比如这段 JS 代码:

const users = [
  {name: '小明', dept: '技术', salary: 8000},
  {name: '小红', dept: '技术', salary: 8000},
  {name: '小刚', dept: '销售', salary: 7500}
];

// 按薪资排序
users.sort((a, b) => a.salary - b.salary);
// 小明和小红顺序不会变,因为 JS sort 是稳定的

但如果你在性能敏感的场景,比如嵌入式系统或者高频交易后台,就得权衡一下:稳不稳,值不值得多花那点资源。

说到底,排序要不要稳定,不是技术上的对错题,而是业务需求的选择题。你得知道它是什么,也得明白自己要什么。