C中的Quicksort实现使用第一个元素作为pivot

时间:2015-12-23 05:44:34

标签: c algorithm sorting quicksort

我是stackoverflow的完全初学者,这是我的第一篇文章。如果这不是发布这类查询的正确位置,请原谅。我已根据Coursera中的算法课程中给出的算法编写了Quicksort算法的代码(但它不适用于任何作业)。

基本上,有两个函数Quicksort,它们被称为递归,而partition()函数则返回数据透视的索引。我每次都选择pivot作为数组的第一个元素。我检查了partition()函数,它工作正常,但即使我调用Quicksort()函数后数组也没有排序。

感谢任何帮助。谢谢。

    #include <stdio.h>
    void swap(int *p, int i, int j)
    {
        int temp = *(p+i);
        *(p+i) = *(p+j);
        *(p+j) = temp;
    }

    int partition(int *q, int l, int r)
    {
        int i = l+1, j;
        int p = l;
        int len  = r-l +1;
        for (j = l+1; j < len; j++)
        {
            /*printf("%d \n", j);*/
            if ( *(q+j) < *(q+p) )
            {
                swap(q, i, j);
                i += 1;
            }
        }
        swap(q, l, i-1);
        /*printf("%d", i-1);*/
        return (i-1);
    }

    void quicksort(int *ptr, int low, int high)
    {
        if (low < high)
        {
            int p = partition(ptr, low, high);
            printf("%d\n", p);
            quicksort(ptr, low, p);
            quicksort(ptr, p+1, high);
        }
    }


    int main(){
        int i;
        int a[] = {3, 8, 2, 5, 1, 4, 7, 6};
        int len  = sizeof(a)/sizeof(a[0]);
        for ( i = 0; i < len; ++i)
        {
            printf("%d ", a[i]);
        }
        printf("\n");
        int *ptr = a;
        quicksort(ptr, 0, len-1);
        for (i = 0; i < sizeof(a)/sizeof(a[0]); ++i)
        {
            printf("%d ", a[i]);
        }
        printf("\n");
        return 0;
    }

2 个答案:

答案 0 :(得分:2)

2次更正。

小一:如果在QuickSort函数中阻止

,则在内部更改第3行

quicksort(ptr, low, p);

quicksort(ptr, low, p-1);

这将提高性能。

主要错误:

您的分区功能错误。特别是jl+1r-l+1的循环,因为r-l+1可能小于l+1

如果你愿意,我会为你编写分区功能(如果你遇到任何问题,可以发表评论)虽然我建议你自己做。

编辑:

可能的分区功能:

int partition(int *q, int l, int r){
    int i,j;
    int p = *(q + l);
    for(i = l + 1, j = r; ;){
        while(*(q + i) <= p)
            i++;
        while(*(q + j) >= p)
            j--;
        if(i >= j)
            break;
        swap(q, i, j);
    }
    return i;
}

答案 1 :(得分:1)

评论中注明的变化。

int partition(int *q, int l, int r)
{
    int i = l+1, j;
    int p = l;
                                    /* fix: int len = r-l+1; is not used */
    for (j = l+1; j <= r; j++)      /* fix: j <= r */
    {
        if ( *(q+j) <= *(q+p) )     /* fix: <= */
        {
            swap(q, i, j);
            i += 1;
        }
    }
    swap(q, l, i-1);
    return (i-1);
}

void quicksort(int *ptr, int low, int high)
{
    if (low < high)
    {
        int p = partition(ptr, low, high);
        quicksort(ptr, low, p-1);   /* optimization: p-1 */
        quicksort(ptr, p+1, high);
    }
}

如果有兴趣,Hoare分区方案更快。如果切换到此,请不要忘记将两个快速排序调用更改为快速排序(lo,p)和快速排序(p + 1,hi))。您可能希望将Hoare pivot更改为pivot = A [(lo + hi)/ 2],这将避免排序或反向排序数组的最坏情况问题。

http://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme