我试图理解为什么heapsort不稳定。 我用Google搜索了这个,但没有找到一个好的,直观的解释。
我理解稳定排序的重要性 - 它允许我们基于多个键进行排序,这可能是非常有益的(即,进行多次排序,每次都基于不同的键。因为每种排序都会保留相对顺序对于元素,先前的排序可以相加,以给出按多个条件排序的元素的最终列表。 但是,为什么heapsort也不会保留这个呢?
感谢您的帮助!
答案 0 :(得分:35)
堆排序不稳定的例子
考虑数组21 20a 20b 12 11 8 7
(已经采用最大堆格式)
此处20a = 20b
只是为了区分我们将其表示为20a
和20b
虽然第一个21
的heapsort被删除并放在最后一个索引中,但20a
被删除并放在最后但只有一个索引而20b
放在最后但是两个索引中,所以在堆排序之后数组看起来像
7 8 11 12 20b 20a 21
。
它不保留元素的顺序,因此不能稳定
答案 1 :(得分:22)
heapsort结果的最后一个序列来自于以纯粹的大小顺序(基于关键字段)从创建的堆中删除项目。
有关原始序列中项目排序的任何信息在堆创建阶段都会丢失,这是首先出现的。
答案 2 :(得分:18)
稳定意味着如果两个元素具有相同的键,则它们保持相同的顺序或位置。但是Heap排序并非如此。
Heapsort 不稳定,因为堆上的操作可以更改相等项的相对顺序。
来自here:
当排序(按升序)时,heapsort第一个峰值最大 元素并将其放在列表的最后一个。所以,有的元素 先被挑选,保持最后和被挑选的元素 第二个停留在排序列表中的倒数第二个元素。
同样,Build-Max-Heap过程可以保留顺序 在构建堆树时具有相同的值(例如:3a,3b)。用于提取 它也可以从root工作的最大元素并尝试保留 树的结构(Heapify的更改除外)。
那么,对于具有相同值[3a,3b]的元素选择,会发生什么 在3b之前的3a,但是将3a放在3b的右边。所以,正如名单所示 按升序排序,我们在列表中的3a之前得到3b。
如果您尝试使用(3a,3b,3b)进行操作,那么您可以将其视觉化 情况。
答案 3 :(得分:1)
假设取一个大小为n的数组(任意值),如果堆中有两个连续的元素(假设为15),并且它们的父索引的值为4和20.(这是实际的顺序(.... 4,20,.....,15,15 .....)。4和15的相对顺序保持相同但是20> 15,第二个15到达(交换),如堆排序中所定义的算法,相对顺序消失了。
答案 4 :(得分:1)
稳定排序算法对元素进行排序,以便在输出中也保持输入中重复元素的顺序。
堆排序包括两个步骤:
1。堆创建期间的订单中断
假设输入数组为{1,5,2,3,2,6,6,2},为了查看2的顺序,假设它们为2a,2b和2c,因此该数组为{1 ,5、2a,3、2b,6、2c}
现在,如果您从中创建一个堆(此处为最小堆),则其数组表示形式将是{1、2b,2a,3、5、6、2c},其中2a和2b的顺序已更改。 / p>
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)在堆排序数组中的顺序与输入中出现的顺序不同,因此堆排序不稳定!
答案 5 :(得分:0)
我知道这是一个迟到的答案,但我会在这里加上我的2美分。 考虑一个包含3个整数的简单数组。 2,2,2现在如果你使用build max heap函数构建一个最大堆,你会发现存储输入的数组没有改变,因为它已经是Max heap形式。现在,当我们在堆排序的第一次迭代中将树的根放在数组的末尾时,数组的稳定性已经消失。所以你有一个简单的堆排序不稳定的例子。