【问题标题】:Why isn't heapsort stable?为什么堆排序不稳定?
【发布时间】:2013-10-20 15:21:41
【问题描述】:

我试图理解为什么 heapsort 不稳定。 我用谷歌搜索了这个,但没有找到一个好的、直观的解释。

我了解稳定排序的重要性——它允许我们基于多个键进行排序,这非常有益(即,进行多次排序,每个排序基于不同的键。因为每个排序都会保留相对顺序的元素,以前的排序可以加起来给出一个按多个标准排序的元素的最终列表)。 但是,为什么 heapsort 不保留这个呢?

感谢您的帮助!

【问题讨论】:

    标签: sorting heapsort stable-sort


    【解决方案1】:

    稳定排序算法对元素进行排序,使得输入中重复元素的顺序在输出中也保持不变。

    堆排序涉及两个步骤:

    • 堆创建
    • 从堆树中删除根元素并将其添加到将按顺序排序的新数组中

    1.堆创建期间的订单中断

    假设输入数组是 {1, 5, 2, 3, 2, 6, 2},为了查看 2 的顺序,假设它们是 2a、2b 和 2c,所以数组是 {1 , 5, 2a, 3, 2b, 6, 2c}

    现在,如果您从中创建一个堆(此处为最小堆),它的数组表示将是 {1, 2b, 2a, 3, 5, 6, 2c},其中 2a 和 2b 的顺序已经改变。

    2。删除根元素期间的顺序中断

    现在,当我们必须从堆中删除根元素(在我们的例子中为 1)以将其放入另一个新数组时,我们将其与最后一个位置交换并从那里删除,因此将堆更改为 {2c, 2b , 2a, 3, 5, 6}。我们重复相同的操作,这次我们将从堆中删除“2c”并将其放在我们放置“1”的数组末尾。

    当我们完成重复此步骤直到堆为空并且每个元素都转移到新数组时,新数组(已排序)看起来像 {1, 2c, 2b, 2a, 3, 5, 6}。

    堆排序的输入: {1, 5, 2a, 3, 2b, 6, 2c} --> 输出: {1, 2c, 2b, 2a, 3, 5, 6}

    因此我们看到重复元素(2)在堆排序数组中的顺序与它们在输入中出现的顺序不同,因此堆排序不稳定!

    【讨论】:

      【解决方案2】:

      我知道这是一个迟到的答案,但我会在这里加上我的 2 美分。 考虑一个由 3 个整数组成的简单数组。 2,2,2 现在如果你使用 build max heap 函数来构建一个 max heap,你会发现存储输入的数组并没有改变,因为它已经是 Max heap 形式了。现在,当我们在堆排序的第一次迭代中将树的根放在数组的末尾时,数组的稳定性已经消失了。所以这里有一个堆排序不稳定的简单例子。

      【讨论】:

      • 我认为这应该是一种方式。
      【解决方案3】:

      假设取一个大小为 n(任意值)的数组,如果堆中有两个连续的元素(假设 15),并且它们的父索引的值如 4 和 20。(这是实际顺序(... 4,20 ,.....,15,15.....). 4 和第一个 15 的相对顺序保持不变,但是当 20>15 时,第二个 15 排在前面(交换),如堆排序中所定义算法,相对顺序没了。

      【讨论】:

        【解决方案4】:

        堆排序不稳定的例子

        考虑数组21 20a 20b 12 11 8 7(已经是最大堆格式)

        这里20a = 20b只是为了区分我们将它们表示为20a20b的顺序

        首先将21 删除并放在最后一个索引中,然后删除20a 并将其放在最后一个索引中,然后将20b 放在最后一个但两个索引中,因此堆排序后数组看起来像

        p>

        7 8 11 12 20b 20a 21.

        它不保留元素的顺序,因此不能稳定

        【讨论】:

        • 如果我们开始将元素粘贴到不同的数组中并从最左边的索引开始,即 0。那么,最大的元素粘贴在索引 0 处。
        • @AvinashKumar,如果您打算保持订单并保持稳定,则时间复杂度不会是 O(n logn)。并且将最大的元素推到列表的最前面也无济于事,它可以解决最大元素的问题,但较低顺序的元素(如第二大元素)仍然可能处于不稳定的排序状态。跨度>
        【解决方案5】:

        稳定意味着如果两个元素具有相同的键,它们将保持相同的顺序或位置。但堆排序并非如此。

        堆排序不稳定,因为堆上的操作会改变相等项的相对顺序。

        来自here

        排序时(按升序)堆排序首先达到最大的峰值 元素并将其放在列表的最后。所以,有 最先被选中,最后保持和被选中的元素 second 停留在排序列表中的倒数第二个元素。

        同样,Build-Max-Heap 过程可以保持顺序 在构建堆树时具有相同的值(例如:3a,3b)。用于提取 它也从根开始工作并尝试保留的最大元素 树的结构(Heapify 的变化除外)。

        那么,对于具有相同值 [3a,3b] 堆排序的元素会发生什么 3a 在 3b 之前,但将 3a 放在 3b 的右侧。所以,因为列表是 按升序排序,我们在列表中得到 3b 在 3a 之前。

        如果您尝试使用 (3a,3b,3b) 进行堆排序,那么您可以将 情况。

        【讨论】:

          【解决方案6】:

          堆排序结果的最终序列来自于从创建的堆中以纯大小顺序(基于键字段)删除项目。

          在堆创建阶段,原始序列中的项目排序的任何信息都丢失了。

          【讨论】:

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