Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 霍尔&x27;s分区工作不正常(快速排序)_C++_Algorithm_Quicksort - Fatal编程技术网

C++ 霍尔&x27;s分区工作不正常(快速排序)

C++ 霍尔&x27;s分区工作不正常(快速排序),c++,algorithm,quicksort,C++,Algorithm,Quicksort,所以在遵循了Cormen的快速排序和hoares分区算法之后,这就是我能够生成的代码。数组中有一些未初始化的元素/垃圾元素,我一辈子都搞不懂为什么。。。我以为我完全按照书上写的那样遵循了算法 以下是本书中的伪代码: HOARE-PARTITION(A, p, r) 1 x = A[p] 2 i = p - 1 3 j = r + 1 4 while TRUE 5 repeat 6 j = j - 1 7 until A[j] <= x 8 repeat

所以在遵循了Cormen的快速排序和hoares分区算法之后,这就是我能够生成的代码。数组中有一些未初始化的元素/垃圾元素,我一辈子都搞不懂为什么。。。我以为我完全按照书上写的那样遵循了算法

以下是本书中的伪代码:

HOARE-PARTITION(A, p, r)
1 x = A[p]
2 i = p - 1
3 j = r + 1
4 while TRUE
5     repeat
6        j = j - 1
7     until A[j] <= x
8     repeat
9        i = i + 1
10    until A[i] >= x
11    if i < j
12        exchange A[i] with A[j]
13    else return j
提前感谢您的帮助…谢谢

编辑 将测试用例调用更改为快速排序(arr,0,9)修复了这种情况

但是,使用反向排序数组作为输入,这就是输出:

arr2 is:
30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
arr2 after quicksort :
1 3 5 7 9 11 13 15 17 19 20 21 18 22 16 23 14 24 12 25 10 26 8 27 6 28 4 29 2 30
使用此测试代码:

int arr2[30];
fillArrayReverse(arr2, 30);
cout << "arr2 is :" << endl;
for(int i = 0; i < 30; i++){
    cout << arr2[i] << " ";
}
cout << endl;
quickSort(arr2, 0, 29);
cout << "arr2 after quicksort: " << endl;
for(int i = 0; i < 30; i++){
    cout << arr2[i] << " ";
}
cout << endl;
int-arr2[30];
fillArrayReverse(arr2,30);

cout这是测试代码的问题。第三个参数应该是最后一个元素的索引,而不是元素数:

quickSort(tarr, 0, 9);
你的读数超过了数组的末尾

有关霍尔分区、快速排序和Cormen等的更多信息,请参阅


解决其他问题的简单方法是将hoare_partition()改为
returni
,而不是j。有关更多详细信息,请参阅链接(据报道,这是本书中的一个错误)。

这是测试代码的问题。第三个参数应该是最后一个元素的索引,而不是元素数:

quickSort(tarr, 0, 9);
你的读数超过了数组的末尾

有关霍尔分区、快速排序和Cormen等的更多信息,请参阅


解决其他问题的简单方法是将hoare_partition()改为
returni
,而不是j。有关更多详细信息,请参阅链接(据报道,这是本书中的一个错误)。

本书中的psuedocode是正确的。问题不在于返回了
j
(这是正确的),而在于
快速排序
函数本身。它实际上应该是这样的:

void quickSort( int arr[], int p, int r )
{
    if( p < r )
    {
        int q = hoare_partition( arr, p, r );
        quickSort( arr, p, q );
        quickSort( arr, q + 1, r );
    }
}
void快速排序(int-arr[],int-p,int-r)
{
if(p

请注意,我们在第一次调用
quickSort
时删除了
q-1
,并将其替换为
q
。在此之前,我们基本上跳过了轴心点,只对围绕轴心点的项目进行排序。在快速排序上查看霍尔分区psuedocode后,我注意到了这种差异。

书中的psuedocode是正确的。问题不在于返回了
j
(这是正确的),而在于
快速排序
函数本身。它实际上应该是这样的:

void quickSort( int arr[], int p, int r )
{
    if( p < r )
    {
        int q = hoare_partition( arr, p, r );
        quickSort( arr, p, q );
        quickSort( arr, q + 1, r );
    }
}
void快速排序(int-arr[],int-p,int-r)
{
if(p

请注意,我们在第一次调用
quickSort
时删除了
q-1
,并将其替换为
q
。在此之前,我们基本上跳过了轴心点,只对围绕轴心点的项目进行排序。在快速排序上查看霍尔分区psuedocode后,我注意到了这种差异。

在书中说“要对整个数组a进行排序,最初的调用是快速排序(a,1,a.length)。”但书中再次提到了1索引数组。所以这就是为什么它使用长度而不是长度-1…它仍然不适用于反向排序的数组,对我的问题进行了详细的编辑,在书中说“要对整个数组进行排序,最初的调用是快速排序(a,1,a.length)”,但书中再次使用了1索引数组。所以这就是为什么它使用长度而不是长度-1…它在反向排序数组上仍然不起作用,对我的问题进行了详细的编辑正如您在对答案的评论中所指出的,您确实需要注意基于0的数组而不是基于1的数组。您确实需要注意基于0的数组而不是基于1的数组,正如你在对答案的评论中所指出的那样。谢谢你发布这篇文章,另一个答案说你应该返回i而不是j,这显然是错误的。霍尔的要点不是将数组分割成
[小于分区的项]分区元素[大于或等于分区的项]
,而是将数组分割成
[小于分区的项][大于或等于分区的项]
。正如您所提到的,然后我们对两个子数组进行快速排序-但与Lomuto分区不同,分区元素尚未位于正确的位置,因此它必须包含在对快速排序的递归调用中。感谢您发布此消息,另一个答案显然是错误的,它指出您应该返回i而不是j。霍尔的要点不是将数组分割成
[小于分区的项]分区元素[大于或等于分区的项]
,而是将数组分割成
[小于分区的项][大于或等于分区的项]
。正如您所提到的,然后我们对这两个子数组进行快速排序—但与Lomuto分区不同,分区元素尚未位于正确的位置,因此它必须包含在对快速排序的递归调用中。
void quickSort( int arr[], int p, int r )
{
    if( p < r )
    {
        int q = hoare_partition( arr, p, r );
        quickSort( arr, p, q );
        quickSort( arr, q + 1, r );
    }
}