c中的Quicksort实现

时间:2014-08-25 11:18:59

标签: c quicksort

我有一个快速排序程序,如图所示执行。但最后一个元素没有被排序。任何人都可以告诉我如何修改程序以获得正确的结果。

#include <stdlib.h>
#include <stdio.h>

static void swap(void *x, void *y, size_t l)
{
    char *a = x, *b = y, c;
    while(l--)
    {
        c = *a;
        *a++ = *b;
        *b++ = c;
    }
}

static void sort(char *array, size_t size, int (*cmp)(void*,void*), int begin, int end)
{
    if (end > begin)
    {
        void *pivot = array + begin;
        int l = begin + size;
        int r = end;
        while(l < r)
        {
            if (cmp(array+l,pivot) <= 0)
            {
                l += size;
            }
            else if ( cmp(array+r, pivot) > 0 )
            {
                r -= size;
            }
            else if ( l < r )
            {
                swap(array+l, array+r, size);
            }
        }
        l -= size;
        swap(array+begin, array+l, size);
        sort(array, size, cmp, begin, l);
        sort(array, size, cmp, r, end);
    }
}

void qsort(void *array, size_t nitems, size_t size, int (*cmp)(void*,void*))
{
    sort(array, size, cmp, 0, (nitems-1)*size);
}

typedef int type;

int type_cmp(void *a, void *b){ return (*(type*)a)-(*(type*)b); }

int main(void)
{ /* simple test case for type=int */
    int num_list[]={5,4,3,2,1};
    int len=sizeof(num_list)/sizeof(type);
    char *sep="";
    int i;
    qsort(num_list,len,sizeof(type),type_cmp);
    printf("sorted_num_list={");
    for(i=0; i<len; i++){
        printf("%s%d",sep,num_list[i]);
        sep=", ";
    }
    printf("};\n");
    return 0;
}

结果:

sorted_num_list={2, 3, 4, 5, 1};

为什么?

我尝试过(nitems)*size。但是当我为字符串尝试相同时,它会给我错误

2 个答案:

答案 0 :(得分:2)

问题来自这一行:

sort(array, size, cmp, 0, (nitems-1)*size);

nitems是你的项目数量,这里5,你是减去一个,所以你的快速排序只会排序4个第一个元素。删除-1,它将起作用。

sort(array, size, cmp, 0, nitems*size);

答案 1 :(得分:0)

这里有2个错误......

首先将qsort()个函数名称更改为qsort_user()或任何其他名称,然后更改为qsort(),因为qsort()stdlib.h中定义的标准函数


然后更改此行

  sort(array, size, cmp, 0, (nitems-1)*size);

  sort(array, size, cmp, 0, (nitems)*size);