C++ 在Quicksort(参考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

我使用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}
上进行分区。对于这个
子数组
,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