Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ArrayList.Sort应该是带有IComparer的稳定排序,但不是?_C#_Sorting_Arraylist_Stability - Fatal编程技术网

C# ArrayList.Sort应该是带有IComparer的稳定排序,但不是?

C# ArrayList.Sort应该是带有IComparer的稳定排序,但不是?,c#,sorting,arraylist,stability,C#,Sorting,Arraylist,Stability,排序是一种保持具有相同值的元素的相对顺序的排序 上的文档表示,如果提供了i比较程序,排序是稳定的: 如果comparer设置为null,则此方法执行比较排序(也称为不稳定排序);也就是说,如果两个元素相等,它们的顺序可能不会被保留。相反,稳定排序保留相等元素的顺序。要执行稳定排序,必须实现自定义IComparer接口 除非我遗漏了什么,否则下面的测试用例显示,ArrayList.Sort没有使用稳定排序: internal class DisplayOrdered { public in

排序是一种保持具有相同值的元素的相对顺序的排序

上的文档表示,如果提供了
i比较程序
,排序是稳定的:

如果comparer设置为null,则此方法执行比较排序(也称为不稳定排序);也就是说,如果两个元素相等,它们的顺序可能不会被保留。相反,稳定排序保留相等元素的顺序。要执行稳定排序,必须实现自定义IComparer接口

除非我遗漏了什么,否则下面的测试用例显示,
ArrayList.Sort
没有使用稳定排序:

internal class DisplayOrdered {
    public int ID { get; set; }
    public int DisplayOrder { get; set; }
    public override string ToString() {
        return string.Format("ID: {0}, DisplayOrder: {1}", ID, DisplayOrder);
    }
}

internal class DisplayOrderedComparer : IComparer {
    public int Compare(object x, object y) {
        return ((DisplayOrdered)x).DisplayOrder - ((DisplayOrdered)y).DisplayOrder;
    }
}

[TestFixture]
public class ArrayListStableSortTest {

    [Test]
    public void TestWeblinkCallArrayListIsSortedUsingStableSort() {
        var call1 = new DisplayOrdered {ID = 1, DisplayOrder = 0};
        var call2 = new DisplayOrdered {ID = 2, DisplayOrder = 0};
        var call3 = new DisplayOrdered {ID = 3, DisplayOrder = 2};
        var list = new ArrayList {call1, call2, call3};

        list.Sort(new DisplayOrderedComparer());

        // expected order (by ID): 1, 2, 3 (because the DisplayOrder
        // is equal for ID's 1 and 2, their ordering should be
        // maintained for a stable sort.)
        Assert.AreEqual(call1, list[0]); // Actual: ID=2 ** FAILS 
        Assert.AreEqual(call2, list[1]); // Actual: ID=1
        Assert.AreEqual(call3, list[2]); // Actual: ID=3
    }
}
我错过什么了吗?如果不是,这是文档错误还是库错误


显然,使用in-Linq可以提供稳定的排序。

文档似乎在说,使用
ArrayList.sort获得稳定排序的唯一方法是使用
IComparer
,它以某种方式“知道”正在比较的项的索引(我们可以想象通过在集合上运行初始过程来实现这一点),并将该信息用作其他相等元素的连接断路器


虽然我同意文档的措辞还有很多需要改进的地方,但是如果没有考虑比较的项目的索引的任何旧的比较器都会神奇地变成一个本质上不稳定的排序算法(这就是<代码> ARAYLISTRO.REST ),这真的是没有意义的。进入稳定状态。

评论的目的是否可能是“您需要实现自己的IComparer以强制排序保持稳定”,而不是“如果您实现自己的IComparer,排序将隐含稳定”?这不是实现比较的好方法。你确定你没有陷入此处描述的谬误:编辑:呸,在试图找到链接时被揍了一顿:D@Mark-Eric的观点提出了一些我不知道的好观点。实际上,我改变了本文中使用System.Integer32.CompareTo()的比较器因为我认为它可能更容易理解。我想我应该留下它。@Mark Wow,我希望我能+1你的链接。我一直认为减法是一种方便的“计算机”方式来表示比较。
glow.levelUp()
谢谢!的确如此。
ArrayList.Sort
的当前实现只是调用
Array.Sort
,而不管使用的是
IComparer
Array.Sort
更明确地被记录为使用了一种不稳定的快速排序。尽管这显然不是我在文档中所假设的,但它似乎是一种合理的解释保留。我的假设是,每当以稳定的排序传递
i比较程序时,都会使用它。但是,正如LukeH指出并查看源代码所揭示的那样,情况并非如此。