【问题标题】:Why Selection sort can be stable or unstable为什么选择排序可以稳定或不稳定
【发布时间】:2013-12-24 12:58:09
【问题描述】:

我知道selection sort 可以实现为稳定或不稳定。但我想知道它是怎么回事。我认为排序算法只能稳定或不稳定。谁能解释一下?

【问题讨论】:

    标签: arrays algorithm sorting


    【解决方案1】:

    基本上在selection sort 中,每个“回合”结束时发生的交换可以改变具有相同值的项目的相对顺序。

    例如,假设您将4 2 3 4 1selection sort 排序。

    第一个“回合”将遍历每个元素,寻找最小元素。它会发现 1 是最小元素。然后它将 1 交换到第一个位置。这将导致第一个位置的 4 进入最后一个位置:1 2 3 4 4

    现在 4 的相对顺序已经改变。原始列表中的“第一个”4 已移至其他 4 之后的位置。

    记住stable的定义是这样的

    保持相同值元素的相对顺序。

    好吧,selection sort 的工作原理是在一组值中找到“最小”值,然后将其与第一个值交换

    代码:

    2, 3, 1, 1 # 扫描 0 到 n 并找到“最小”值

    1, 3, 2, 1 # 将 'least' 与元素 0 交换。

    1, 3, 2, 1 # 扫描 1 到 n 并找到“最小”值

    1, 1, 2, 3 # 将 'least' 与元素 1 交换。

    ...依此类推,直到它被排序。

    为了使其稳定,不要交换值,而是插入“最小”值

    代码:

    2, 3, 1, 1 # 扫描 0 到 n 并找到“最小”值

    1, 2, 3, 1 # 在 pos 0 处插入 'least',将其他元素向后推。

    1, 3, 2, 1 # 扫描 1 到 n 并找到“最小”值

    1, 1, 2, 3 # 在位置 1 插入 'least',将其他元素往后推。

    ...依此类推,直到它被排序。

    修改不稳定的选择排序算法使其变得稳定应该不会太难。

    【讨论】:

    • 不错的答案。谢谢。但如果我理解正确,使用“插入”而不是“交换”实现的选择排序会偏离其canonical algorithm definition,因此它不再是同一种动物。稳定的代价是“插入”的开销远大于“交换”。 @Alma-Do 对此主题有更好的解释。
    • 很好的解释。如果第二个示例(2,3,1,1)在正常算法中不稳定并且在修改后的算法后稳定。无论哪种方式都稳定。第一个一个更好的例子。
    【解决方案2】:

    在一般情况下 - 你是不正确的。选择排序是unstable。这来自它的定义。因此,您显然对一个自定义案例感到困惑。

    可以稳定 - 通常,只有linked lists。为此(经典方式,O(1) 内存)——而不是交换,必须将最小元素链接到未排序的部分,从而使整个算法稳定。这就是“实现”的区别——显然,由于数据结构的特殊性,只有在这种情况下才会产生稳定性。 It has nothing to do with common case, when selection sorting is unstable

    【讨论】:

      【解决方案3】:

      假设我有这个数组:

      A = {3, 3, 1}
      

      从位置 0 开始,选择排序将搜索最小值并将当前元素与最小值交换。对于A,我们将第一个3 替换为1,第二步什么也不做。

      这是不稳定的,因为第一个 3 应该在第二个之前出现。如果你使用链表而不是数组,并且在正确的位置插入一个元素而不是交换,选择排序是稳定的。

      【讨论】:

        【解决方案4】:

        排序路由是选择排序这一事实并没有定义它的所有内容。在不同的实现中仍有可能做出不同的决定,并且不同的选择可能会产生稳定或不稳定的排序。 (大多数可以稳定的排序不一定是稳定的;通常,有趣的理论问题是排序是否可以稳定地实现。)

        【讨论】:

          【解决方案5】:
          • 首先,您必须了解,选择排序没有什么不稳定的东西,因为它在很大程度上取决于您使用的特定数据结构。
          • 例如,假设我们有一个数组为 4 2 4 1,使用传统方法对该数组进行排序后,结果将是 1 2 4 4 , 简单的。但是在第一轮迭代中,出现在第 0 个索引上的 4 将被放置在最后一个索引上出现在第 0 个索引上。 ( 1 2 4[第二个索引] 4[从第 0 个索引])
          • 如果被问到!您可以在实现中稍作修改,而不是交换数字,而是在第一轮中选择最小元素,然后将该元素放在正确的位置并移动整个数组。我知道换档操作的成本可能比换档高,但这是我能想到的最好的了。
          • 如果您担心移位操作,您可以使用链表而不是数组,并在 O(1) 时间内在其适当位置插入适当的元素。

          【讨论】:

            猜你喜欢
            • 2013-10-20
            • 1970-01-01
            • 2011-08-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多