【问题标题】:What is the benefit for a sort algorithm to be stable?排序算法稳定有什么好处?
【发布时间】:2009-04-30 19:20:56
【问题描述】:

如果一个排序保持具有相同键的元素的相对顺序,则称该排序是稳定的。我想我的问题是,保持这种相对顺序有什么好处?有人可以举个例子吗?谢谢。

【问题讨论】:

标签: algorithm sorting


【解决方案1】:

它使您的排序能够通过多个条件“链接”。

假设您有一张随机排列的名字和姓氏的表格。如果先按名字排序,然后再按姓氏排序,稳定的排序算法将确保姓氏相同的人按名字排序。

例如:

  • 史密斯,阿尔弗雷德
  • 史密斯,泽德

将保证顺序正确。

【讨论】:

  • 为什么不在比较谓词中包含这个名字和姓氏?然后你只需要排序一次。
  • 它在您不提前知道条件时很有用。设想一个列表视图,其中用户单击一列进行排序,然后单击另一列进行进一步排序。
  • 这个答案应该被接受。我只花了半个小时看其他解释技术定义的答案(这对谷歌来说很容易),但没有明确表示使用稳定性的底线。
【解决方案2】:

如果排序算法保持重复键的顺序,则它是稳定的。

好的,好的,但是为什么这很重要?好吧,当我们希望根据不同的键对相同的数据进行多次排序时,就会出现排序算法中的“稳定性”问题。

有时数据项有多个键。例如,可能是一个(唯一的)主键,例如社会保险号或学生证号,以及一个或多个辅助键,例如居住城市或实验室部分。而且我们很可能希望根据不止一个键对这些数据进行排序。麻烦的是,如果我们按照一个key对相同的数据进行排序,然后再按照第二个key进行排序,那么第二个key可能会破坏第一个排序所达到的排序。但如果我们的第二个排序是稳定排序,则不会发生这种情况。

来自Stable Sorting Algorithms

【讨论】:

  • 我没有投反对票,但您所做的只是从网站复制数据。其他人实际上是为了解释这个问题而麻烦,所以也许这就是原因。对我来说似乎不值得,但其他人可能会这么认为。
  • IMO 并没有重新发明轮子,也没有引用适当的归属。 YMMV。
  • 赞成;简明扼要的报价和可靠来源的链接比在这个地方漂浮的许多答案要好。
【解决方案3】:

优先级队列就是一个例子。假设你有这个:

  1. (1, "鲍勃")
  2. (3, "账单")
  3. (1, "简")

如果你从小到大排序,不稳定的排序可能会这样做。

  1. (1, "简")
  2. (1, "鲍勃")
  3. (3, "账单")

...但随后“jane”领先于“bob”,尽管它应该是相反的。

通常,它们对于在多个步骤中对多个条目进行排序很有用。

【讨论】:

  • 使用正确的比较逻辑不会发生这种情况。 (即也比较字符串)
【解决方案4】:

并非所有排序都基于整个值。考虑一份人员名单。我可能只想按他们的名字而不是他们的所有信息对它们进行排序。使用稳定的排序算法,我知道如果我有两个名为“John Smith”的人,那么他们的相对顺序将被保留。

Last     First       Phone
-----------------------------
Wilson   Peter       555-1212
Smith    John        123-4567
Smith    John        012-3456
Adams    Gabriel     533-5574

由于两个“John Smith”已经“排序”(它们按我想要的顺序排列),我不希望它们改变位置。如果我最后对这些项目进行排序,那么首先使用不稳定的排序算法,我可能会得到这样的结果:

Last     First       Phone
-----------------------------
Adams    Gabriel     533-5574
Smith    John        123-4567
Smith    John        012-3456
Wilson   Peter       555-1212

这是我想要的,否则我可能会得到这个:

Last     First       Phone
-----------------------------
Adams    Gabriel     533-5574
Smith    John        012-3456
Smith    John        123-4567
Wilson   Peter       555-1212

(您会看到两个“John Smith”互换了位置)。这不是我想要的。

如果我使用稳定的排序算法,我肯定会得到第一个选项,这就是我所追求的。

【讨论】:

  • 赞成;没有其他人提到,保留“相对”排序。
【解决方案5】:

一个例子:

假设您有一个数据结构,其中包含成对的电话号码和拨打电话的员工。每次通话后都会添加一个号码/员工记录。一些电话号码可能由多个不同的员工拨打。

此外,假设您想按电话号码对列表进行排序,并为拨打任何给定号码的前 2 个人提供奖金。

如果您使用不稳定的算法进行排序,您可能无法保留给定号码的呼叫者的顺序,并且可能会给错误的员工提供奖金。

稳定的算法可确保每个电话号码的正确 2 名员工获得奖金。

【讨论】:

    【解决方案6】:

    这意味着如果您想按专辑和曲目编号排序,您可以先单击曲目编号,然后排序 - 然后单击专辑名称,每个专辑的曲目编号都会保持正确的顺序。

    【讨论】:

    • 我想知道有多少人意识到它是这样工作的?看起来几乎像反向波兰表示法。
    【解决方案7】:

    一种情况是您想按多个键进行排序。例如,要对名字/姓氏对列表进行排序,您可以先按名字排序,然后按姓氏排序。

    如果您的排序不稳定,那么您将失去第一次排序的好处。

    【讨论】:

      【解决方案8】:

      对多个键进行稳定排序的优点是值得怀疑的,您始终可以使用一次比较所有键的比较。如果您一次对一个字段进行排序,这只是一个优势,例如单击列标题时 - Joe Koberg 就是一个很好的例子。

      如果您有能力在记录中添加一个序列号,任何排序都可以转换为稳定排序,并在出现等效键时将其用作决胜局。

      当原始订单本身具有某种意义时,最大的优势就出现了。我想不出一个很好的例子,但我看到 JeffH 在我考虑的时候就这样做了。

      【讨论】:

        【解决方案9】:

        假设您正在对具有两个字段的输入集进行排序,并且您只对第一个字段进行排序。 '|'字符划分字段。

        在输入集中,您有很多条目,但是,您有 3 个看起来像的条目

        。 . . AAA|牵引 . . . AAA|汽车租赁 . . . AAA|水暖 . . .

        现在,当您完成排序后,您希望其中包含 AAA 的所有字段都放在一起。

        稳定的排序将为您提供: . . . AAA|牵引 AAA|汽车租赁 AAA|水暖 . . .

        即,具有相同排序键 AAA 的三个记录在输出中的顺序与它们在输入中的顺序相同。请注意,它们没有按第二个字段排序,因为您没有按记录中的第二个字段排序。

        不稳定的排序会给你: . . . AAA|水暖 AAA|汽车租赁 AAA|牵引 . . .

        请注意,记录仍然仅按第一个字段排序,并且 第二个字段与输入顺序不同。

        不稳定的排序可能会更快。稳定的排序倾向于模仿非计算机科学家/非数学人员在排序时的想法。即,如果您使用索引卡进行插入排序,您很可能会有一个稳定的排序。

        【讨论】:

          【解决方案10】:

          您不能总是一次比较所有字段。举几个例子:(1)内存限制,你正在对一个大磁盘文件进行排序,并且主内存中没有所有记录的所有字段的空间; (2) 对基类指针列表进行排序,其中一些对象可能是派生的子类(您只能访问基类字段)。

          此外,在给定相同输入的情况下,稳定排序具有确定性的输出,这对于调试和测试非常重要。

          【讨论】:

            猜你喜欢
            • 2016-12-02
            • 1970-01-01
            • 2010-12-03
            • 1970-01-01
            • 1970-01-01
            • 2011-08-22
            • 2013-10-20
            • 2023-03-25
            • 1970-01-01
            相关资源
            最近更新 更多