为什么我的C# List.Sort方法会颠倒列表的顺序?

4

我有一个泛型列表,其中包含以下项目:

  • A1 (排序索引 1)
  • A2 (排序索引 2)
  • B1 (排序索引 3)
  • B2 (排序索引 3)
  • B3 (排序索引 3)

它们的比较器采用以下形式:

this.sortIndex.CompareTo(other.sortIndex)

当我对项目列表进行List.Sort()时,输出的顺序如下:
  • A1
  • A2
  • B3
  • B2
  • B1
显然,排序索引已按正确顺序排列,但我真的不希望'B'项被重新排序。
有没有任何调整我可以对比较器进行以解决这个问题?

5个回答

5

如果您不想让相等的项目改变位置,则需要使用“稳定排序”算法。

查看“归并排序”以获取稳定排序算法的示例。这里是C#的实现


5

OrderBy 会保留相等项的顺序:

myList = myList.OrderBy(item => item.SortIndex).ToList();

2

List<T>StableSort()扩展方法可以在这里找到。


1

您可以更改比较器,对值进行二次排序:

if (this.sortIndex.CompareTo(other.sortIndex) == 0) // same sortIndex
{
   return this.Value.CompareTo(other.Value);
}
return 0;

这不是和我发布的例子做的完全一样吗? - Fiona - myaccessible.website
@Fiona:不,代码在次要比较中使用该值,但如果您想使用它,则必须进行一些更正,因为它会通过返回零而混淆主要比较的结果。 - Guffa
啊,我明白了。我没有一个可用的第二个比较方法(虽然我可以添加一个人工的比较方法并且这样做很好),我想要保留的列表顺序是基于一个非常复杂的递归函数的输出。 - Fiona - myaccessible.website

1

Sort使用QuickSort算法,但在比较相等的情况下不保证原始序列。

如果您仍想使用List.Sort,可以添加一个基于原始索引的第二个比较条件,如下所示:

int c = this.sortIndex.CompareTo(other.sortIndex);
if (c == 0)
  c = this.originalIndex.CompareTo(other.originalIndex);
return c;

否则,您可以使用其他“稳定”的算法进行排序(例如LINQ OrderBy)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接