这个问题
partition(A,p,r)
{
x=A[r];
i=p-1;
for j=p to r-1
if(A[j]<=x)
i++;
exchange(A[i],A[j])
exchange(A[i+1],A[r]);
return i+1;
}
这个问题
partition(A,p,r)
{
x=A[r];
i=p-1;
for j=p to r-1
if(A[j]<=x)
i++;
exchange(A[i],A[j])
exchange(A[i+1],A[r]);
return i+1;
}
在某些情况下,您的分区算法将进行一次交换,这将改变相等值的顺序。以下图片帮助展示了您的就地分区算法的工作原理:
我们使用j索引遍历每个值,如果我们看到的值小于分区值,则通过交换它与灰色子数组右侧紧邻元素的位置,将其附加到浅灰色子数组中。浅灰色子数组包含所有<=分区值的元素。现在让我们看看,比如,阶段(c)并考虑三个9位于白色区域开头,后面跟着一个1的情况。也就是说,我们要检查这些9是否<=分区值。我们查看第一个9并发现它不<= 4,因此我们保持它不变,并向前移动j。我们查看下一个9并发现它不<= 4,因此我们也保持它不变,并向前移动j。我们也保持第三个9不变。现在我们查看1并发现它小于分区值,因此我们将其与第一个9交换。然后完成算法时,我们将分区值与i + 1处的值交换,即第二个9。现在我们已经完成了分区算法,并且最初第三个的9现在成为第一个。
如果你愿意添加第二个关键字,任何排序方式都可以转换为稳定排序。第二个关键字应该是指示原始顺序的内容,例如一个序列号。在比较函数中,如果第一个关键字相等,则使用第二个关键字。
当相似元素的原始顺序不改变时,排序是稳定的。由于您的算法交换了相等的元素,因此它不是稳定的。
如果没有交换相等元素,那么它仍然不会是稳定的:
( 1, 5, 2, 5, 3 )
你有两个排序键为“5”的元素。如果因为某种原因比较第2个元素(5)和第5个元素(3),那么5将与3交换,从而违反稳定排序的规则。这意味着仔细选择枢轴元素是不够的,你还必须确保在分区之间复制元素时不会交换原始顺序。
快速排序不稳定。下面是它不稳定的情况。
5 5 4 8
现在在元素大于9的区域,即在j的循环中,如果找到任何一个9,则将其与小于该区域即i区域的元素交换。你的数组将被稳定排序。
来自维基百科:
快速排序是一种比较排序算法,在高效的实现中,不是稳定排序。