【问题标题】:Quick sort: Pivot is the first element that is greater than its neighbor快速排序:枢轴是第一个大于其邻居的元素
【发布时间】:2021-11-28 13:33:57
【问题描述】:

我正在学习快速排序,我发现了一种算法,其中枢轴是第一个大于其邻居的元素,这里是伪代码

void quicksort(int i,int j)
{
    pivotindex=findpivot(i,j);
    if(pivotindex!=-1)
    {
        pivot=a[pivotindex];
        k=partition(i,j,pivot); // l
        quicksort(i,k-1);
        quicksort(k,j);
    }
}


int findpivot(int i, int j)
{
    for i=0 to j
    {
        if(a[i]>a[i+1])
        return(i);

    else if(a[i]<a[i+1])
        return(i+1);

    else
        continue;
    }
return(-1);
}


int partition(int i, int j, int pivot)
{
    int l, r;
    l=i, r=j;
    do
    {
    swap(a[l],a[r]);
    while(a[l]<pivot)
        l=l+1;
    while(a[r]>=pivot)
        r=r-1;
    } while(l<r);
    return(l);
}

这个伪代码可以正常工作吗?

我尝试为此编写 c++ 代码,这是我的代码

#include <iostream>

using namespace std;

void swap(int *i,int *j){
    int temp = *i;
    *i = *j;
    *j = temp;
}


int partition(int l, int r, int idx, int arr[]){
   
    do{
        int index = arr[idx];
        
        swap(&arr[l],&arr[r]);
        
        //cout<<arr[l]<<" "<<arr[r]<<" pivot : "<<index<<endl;
        
        while(arr[l]<index){
            l=l+1;
        }
        while(arr[r]>=index){
            r=r-1;
        }
        
        
    }while(l<r);
    
    return l;

    
}

int findpivot(int l,int r,int arr[]){
    
    for(int i = l; i<=r; i++){
        if(arr[i]>arr[i+1]){
            
            return i;
        } 
        else if(arr[i+1]>arr[i]){
            
            return i+1;
        } 
        else{
            continue;
        }
        
    }
    return(-1);
    
}


void Quicksort(int l, int r,int arr[]){
    
    int idx = findpivot(l,r,arr);

    
    
    if(idx!=-1){
        int pivot = arr[idx];
        
        int  k = partition(l,r,idx,arr);
       
        
        Quicksort(l,k-1,arr);
        Quicksort(k,r,arr);
       
    }

}





int main()
{
    int arr[10] = {19,23,11,43,24,68,98,47,99,89};
    Quicksort(0,9,arr);
    
    cout<<"final"<<endl;
    for(int i =0;i<10;i++){
        cout<<arr[i]<<" ";
    }
    
    
    return 0;
}

我的代码在这些步骤之前都很好,然后它变成了一个无限循环,是我的代码有问题,还是伪代码有问题? {89,23,11,43,24,68,98,47,99,19}

{19,23,11,43,24,68,98,47,99,89}

{19,11,23,43,24,68,98,47,99,89}

{11,19}

谁能帮我解决这个问题。

【问题讨论】:

  • findpivot 的第一行没有意义:for i=0 to j since you lost i
  • findpivot not 通常会返回最大的元素,如果这是本意的话 - 它会返回大于其邻居的第一个元素。此外,使用最小值或最大值作为快速排序的基准,是最差的情况,而不是最好的情况。

标签: c++ algorithm sorting quicksort


【解决方案1】:

除了@stark says in a comment关于findpivot中伪代码迭代中的初始值之外,终止条件显然不正确。您的实现修复了初始值(这可能是一个错字),但重复了终止问题:for(int i = l; i&lt;=r; i++)

但终止条件必须是i &lt; r。如果i 等于r,则循环将访问元素a[r+1],它在范围之外(也可能在数组之外)。此外,该算法依赖于findpivot检测递归结束条件,即范围内所有元素相等时,而不是范围内所有元素和下一个元素是平等的。因此是无限循环。

【讨论】:

  • 我尝试更改这些,但循环仍然没有结束。
  • @AxXxelWolf:你没有提到你尝试了什么改变,所以我不知道你实际上做了什么。我建议的更改是将条件i &lt;= r 替换为i &lt; r,对我来说非常有效。
  • 我编辑了答案以可能使建议的更改更加明显。
  • 我首先将i&lt;r 更改为i&lt;= r,然后将int index = arr[idx]; 放在do while 循环之外,在这两个更改之后程序运行正常。感谢您的帮助。
猜你喜欢
  • 2014-10-25
  • 1970-01-01
  • 2011-08-31
  • 2016-03-29
  • 2017-01-21
  • 1970-01-01
  • 2019-11-23
  • 1970-01-01
  • 2010-09-14
相关资源
最近更新 更多