【发布时间】:2015-12-19 20:52:06
【问题描述】:
我一直在尝试实现 Hoare 分区方法,但我和计算机似乎都无法理解它,因为它是用 Cormen 和 Wikipedia 编写的。 两个来源中的算法如下所示:
algorithm partition(A, lo, hi) is
pivot := A[lo]
i := lo - 1
j := hi + 1
loop forever
do
j := j - 1
while A[j] > pivot
do
i := i + 1
while A[i] < pivot
if i < j then
swap A[i] with A[j]
else
return j
对于以下数组: 9 3 11 55 4 ,使用上述函数对其进行分区后,它将如下所示: 4 3 11 55 9 并且枢轴索引将为2,这是完全错误的。首先,9 和 4 将被交换,因此 i 将变为 2,j 将变为 4。但是,在下一次迭代期间,由于 do while 循环,9 将被跳过并且永远不会再次交换。 我的想法有问题吗? (我认为我在 C++ 中的实现没有任何错误)
#include <iostream>
using namespace std;
int a[100];
int partitie(int st, int dr){
int i,j,x;
x=a[st];
i=st-1;
j=dr+1;
while(true){
do{
j--;
}while(a[j]>x);
do{
i++;
}while(a[i]<x);
if(i<j) swap(a[i],a[j]);
else return j;
}
}
int main() {
int i,n;
cin>>n;
for(i=1;i<=n;i++) cin>>a[i];
cout<<partitie(1,n)<<endl;
for(i=1;i<=n;i++) cout<<a[i]<<" ";
return 0;
}
【问题讨论】:
-
[lo, hi)或[lo, hi]? -
@BrianRodriguez - 快速排序通常是 [lo, hi]。
-
第一次调用 partition 时返回的枢轴索引将是 1,而不是 2。数组分为两个,{4,3} 和 {11,55,9}。
-
@rcgldr 我再次运行上面发布的程序,函数返回 2。再次检查并记住索引从 1 开始,而不是 0。
-
@rptoma - 我错过了您的 C / C++ 示例使用 1 的起始索引,但结果应该相同,数组分为两个,{4,3} 和 { 11,55.9}.
标签: c++ quicksort partitioning