C++ 在Quicksort(参考Cormen的书)中使用的霍尔分区代码运行到无限循环中
我使用Cormen算法书中的霍尔分区编写了快速排序代码。我看不出我的代码中有任何错误,它看起来就像书中的伪代码C++ 在Quicksort(参考Cormen的书)中使用的霍尔分区代码运行到无限循环中,c++,algorithm,quicksort,partitioning,hoare-logic,C++,Algorithm,Quicksort,Partitioning,Hoare Logic,我使用Cormen算法书中的霍尔分区编写了快速排序代码。我看不出我的代码中有任何错误,它看起来就像书中的伪代码 swapping i, j : 0, 8 -2 2 -5 -3 6 0 1 0 -1 4 swapping i, j : 1, 3 -2 -3 -5 2 6 0 1 0 -1 4 p is: 2 swapping i, j : 0, 1 -3 -2 -5 2 6 0 1 0 -1 4 p is: 0 完成上述交换后,该代码最终在子数组{-3,-2}上进行分区。对于这个子数组,pi
swapping i, j : 0, 8
-2 2 -5 -3 6 0 1 0 -1 4
swapping i, j : 1, 3
-2 -3 -5 2 6 0 1 0 -1 4
p is: 2
swapping i, j : 0, 1
-3 -2 -5 2 6 0 1 0 -1 4
p is: 0
完成上述交换后,该代码最终在子数组{-3,-2}
上进行分区。对于这个子数组
,pivot是-3
,而分区()返回0
作为索引(j)
。由于此子数组已使用pivot-3
在0th index
位置进行排序,因此每次快速排序时都不会进行任何更改。所以qsort永远循环
有人能告诉我这与书中的霍尔分区有什么不同吗?如果相同,为什么不起作用
void swap(int *a, int i, int j) {
cout << "swapping i, j : " << i << ", " << j << endl;
int tmp = a[i];
a[i] = a[j];
a[j] = tmp; }
int partition(int *a, int len) {
int pivot = a[0];
int i = -1, j = len;
while (true) {
while ( ++i && a[i] < pivot && i< j) {}
while (--j && a[j] > pivot && i <j) {}
if (i < j )
swap(a, i, j);
else
return j ;
} }
void qsort(int a[], int len) {
int p = partition(a, len);
cout << "p is: " << p << endl;
qsort(a, p);
qsort(a+p, len - p ); }
int main(int argc, char *argv[]) {
int a[10] = {-1, 2, -5, -3, 6, 0, 1, 0, -2, 4};
qsort(a, 10); }
无效交换(int*a、int i、int j){
如果在回答中扩展我的注释,partition()
返回基于0的索引,但是需要将数组长度(长度是基于1的)传递到qsort()
,因此它必须是:
void qsort(int a[], int len)
{
int p = partition(a, len);
cout << "p is: " << p << endl;
qsort(a, p + 1); // note p+1 instead of p
qsort(a + p + 1, len - (p + 1)); // note p+1 instead of p
}
现在您必须调用qsort(a,3)
,因为您要对子数组-2-3-5
进行排序对于子数组2 6 0 1 0-1 4
什么时候发生交换i,j:0,1
的?你的意思是交换i,j:0,2
?交换i,j:0,1意味着要交换的数组“a”输入的索引0和索引1处的值正在被交换。我知道了,但我认为索引0
和2
正在被交换ad,在对qsort(a,3)
的第二次调用期间,将原始数组在每次交换后的外观添加到OP中。在第三次交换之后,p为0,子数组为{-3,-2}。在第二次交换之后,p=2
。然后在分区(a,3)
,i
变为0
(正如您正确地说的那样),但j
变为2
(而不是1
),因为-5<-2
(-2
是的轴心)这似乎是对的,qsort(a,p+1)需要进行调用。所以我知道在分区子数组索引0到p是=pivot之后,分区是否会在I==j处返回?我想很有趣的是,Cormen的书中提到,如果我们选择[len-1]作为pivot,那么对于一个[len-1]的数组,该代码将进入无限循环是最大的元素。当[0]是最小的元素,[0]是pivot时,无限循环必须有相应的情况(上面的代码就是这样做的)。对于这种情况,分区应该返回什么?恐怕我不理解您上面提到的用例。
swapping i, j : 0, 8
-2 2 -5 -3 6 0 1 0 -1 4
swapping i, j : 1, 3
-2 -3 -5 2 6 0 1 0 -1 4
p is: 2