【问题标题】:quicksort implementation快速排序实现
【发布时间】:2011-10-02 05:54:25
【问题描述】:

快速排序的以下代码不起作用,我不明白是什么原因。

#include <iostream>
using namespace std;
void exch(int a[],int i,int j){
    int s=a[i];
    a[i]=a[j];
    a[j]=s;

}
int  partition(int a[],int l,int h);
void quick(int a[],int l,int h){
    if (h<=l) return ;
    int j=partition(a,l,h);
    quick(a,l,j-1);
    quick(a,j+1,h);
    }
int partition(int a[],int l,int h){
    int i=l-1;
    int j=h;
    int v=a[l];
    while(true){

        while( a[++i]<v);

        while(a[--j]>v) if (j==i)  break;

            if (i>=j) break;

        exch(a,i,j);

    }

    exch(a,i,h);
    return i;



}
int main(){

    int a[]={12,43,13,5,8,10,11,9,20,17};
    int n=sizeof(a)/sizeof(int);
quick(a,0,n-1);
 for (int  i=0;i<n;i++){
     cout<<a[i]<<"  ";
 }
     return 0;
 }

输出

5  8  9  11  10  17  12  20  13  43

【问题讨论】:

  • 您是否尝试单步执行代码以查看哪里出错了?
  • 没有作业没有,只是训练和测试算法书籍中的代码
  • 我发现通过使用 step into 从调试结果是这个 j -858993460 int 为什么会这样?
  • 我已将您的代码翻译成Cython。它仅比clib 的qsort 快​​约2 倍。

标签: c++ quicksort


【解决方案1】:

在您的 partition 方法中,应该是

int v = a[h]; 

而不是

int v = a[l];

[更新:我刚刚测试了带有该更改的代码,它可以正常工作,输出:

5  8  9  10  11  12  13  17  20  43 

【讨论】:

  • 一个问题@Mitch Wheat,首先非常感谢你的帮助,但问题是有什么区别?我的意思是我们用第一个元素还是最后一个元素表示枢轴元素?这是否意味着如果没有正确选择枢轴,有时快速排序不起作用?
  • 无论选择何种枢轴,该算法始终有效(尽管运行时可能会出现 N^2 最坏情况,但这是另一个话题。)
  • 如果我们想使用条件为 int v = a[l];那么我们应该在代码中的哪个位置进行更改,我想选择第一个元素作为枢轴。
【解决方案2】:

下面是分区步骤的更清晰的实现:

def quicksort(arr, low, high):
    if low > high or low == high:
        return

    pivot = randint(low, high)
    updated_pivot = partition(pivot,arr, low, high)
    quicksort(arr, low, updated_pivot-1)
    quicksort(arr, updated_pivot+1, high)


def partition(pivot, arr, low, high):
    arr[low], arr[pivot] = arr[pivot], arr[low] #now pivot is at 'low' index of current subarray    
    start_of_ = 1 
    curr = 1
    while curr <= high:
       if arr[curr] <= arr[low]:
           arr[start], arr[curr] = arr[curr], arr[start] #making sure all values between index low and index start (exclusive)  are less than or equal to the pivot.
               start+=1 
       curr += 1

    new_pivot_location = start - 1 #the value at index start is the first value greater than the pivot (the range considered in the while loop is exclusive)
    arr[new_pivot_location], arr[low] =arr[low], arr[new_pivot_location]
    return new_pivot_location

示例运行:

输入:

[5,1,3,8, 0,2]
     |
   pivot

分区算法:

[3,1,5,8,0,2] --> after switching pivot's position
 |
pivot

  start
   |
[3,1,5,8,0,2] --> initializing start and curr
   |
  curr

    start
     |
[3,1,5,8,0,2] --> 1 < 3, so we swap 1 & 1, and start++, curr++
     |
    curr

    start
     |
[3,1,5,8,0,2] --> 5 > 3, so we don't swap. Don't move start, curr++
       |
      curr

    start
     |     
[3,1,5,8,0,2] --> 8 > 3, so we don't swap. Don't move start, curr++
         |
        curr

      start
       |
[3,1,0,8,5,2] --> 0 < 3, so we swap 5 and 0. start++, curr++
           |
           curr

        start
         |
[3,1,0,2,5,8] --> 2 < 3, so we swap 8 and 2. start++, curr++
             |
            curr

[2,1,0,3,5,8] --> swap 2 and 3, and reset pivot index.

输出:

[2,1,0,3,5,8]
       |
      pivot

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多