快速排序不是稳定的算法,因为它交换非相邻元素。
请帮我理解这个说法。
我知道如何进行分区以及什么是稳定性。但我无法弄清楚为什么上述原因导致它不稳定?我认为同样的情况也适用于归并排序-尽管它被引用为稳定算法。
考虑以下成对数组在分区过程中的情况,其中比较器只使用整数。字符串只是为了确保我们有两个元素进行比较,它们看起来相等,但实际上是可区分的。
(4, "first"), (2, ""), (3, ""), (4, "second"), (1, "")
根据定义,如果在排序后,比较相同的两个元素(即两个4
)的顺序与排序前相同,则排序是稳定的。
假设我们选择3
作为基准点。两个4
元素将在其后面,而1
和2
将在其前面(还有一些其他细节需要注意,但由于基准点已经处于正确位置,因此我忽略了移动基准点,但你说你理解分区)。
通常情况下,快速排序不会保证分区后两个4
出现在哪里,我认为大多数实现都会反转它们。例如,如果我们使用Hoare的经典分区算法,则数组被分成如下:
(1, ""), (2, ""), (3, ""), (4, "second"), (4, "first")
这违反了排序的稳定性。
由于每个分区都不稳定,整体排序也很可能不稳定。
正如Steve314在评论中指出的那样,归并排序是稳定的,前提是在合并时,如果遇到相等的元素,您总是首先输出来自要合并的两个部分中“下层”的那个元素。也就是说,每次合并都必须像这样,其中“左侧”是来自原始数组较低位置的一侧。
while (left not empty and right not empty):
if first_item_on_left <= first_item_on_right:
move one item from left to output
else:
move one item from right to output
move everything from left to output
move everything from right to output
如果 <=
改成 <
,那么合并就不稳定了。