C# List.Sort(IComparer<T> comparer) 不稳定排序

踩坑

使用List.Sort(IComparer<T> comparer)进行自定义排序时,发现关键字相等的元素排序后先后顺序发生改变。检查自己实现的ICompare<T>.Compare方法逻辑没发现问题。后来查阅MSDN文档发现:

This method uses Array.Sort, which applies the introspective sort as follows:
If the partition size is less than or equal to 16 elements, it uses an insertion sort algorithm
If the number of partitions exceeds 2 log n, where n is the range of the input array, it uses a Heapsort algorithm.
Otherwise, it uses a Quicksort algorithm.
This implementation performs an unstable sort; that is, if two elements are equal, their order might not be preserved. In contrast, a stable sort preserves the order of elements that are equal.
On average, this method is an O(n log n) operation, where n is Count; in the worst case it is an O(n2) operation.

List.Sort这个方法其实也是调用Array.Sort,而Array.Sort的内部实现主要是快速排序
当Partition数据量较小时,使用插入排序;当Partition的数量超过 log n 时,使用堆排序。
快速排序本身是不稳定的排序算法,所以关键字相等的元素在排序后先后位置关系有可能发生改变。

解决方案

再添加一个次关键字SortIndex,这个关键字的值是排序列表元素原本的索引顺序。
对于主关键字相等的元素,再加上这个次关键字进行比较,以保证先后顺序不变。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值