16.8 快速排序之qsort()函数

对于大型数组,“快速排序”是最有效的排序算法之。
它把数组不断分成更小的数组,直到变成单元数组。首先,把数组分成两个部分,一部分的值都小于另一部分的值,这个过程一直持续到数组完全排好序为止。
快速排序算法在c中实现的名称是qsort()。qsort()函数排列数组的数据对象,其原型如下

void qsort(void *base,size_t nameb,size_t size,int (*compar)(const void *,const void *));

第一个参数是指针,指向待排序数组的首元素。
第二个参数是待排序项的数量,函数原型把该值转换成size_t类型。size_t定义在标准头文件中,是sizeof运算符的返回整数类型。
由于qsort()把第一个参数转换成void指针,所以qsort()不知道数组中每个元素的大小,为此,函数原型用第三个参数补偿这一信息,如果排序double类型的数组,那么第三个参数就是sizeof(double),sizeof()函数功能为获得保证能容纳实现所建立的最大对象的字节大小。
最后qsort()还需要一个指向函数的指针,这个被指针指向的比较函数用于确定排序的顺序。该函数接收两个参数:分别指向待比较的两个指针,如果第一项的值大于第二项,比较函数返回正数;如果两项相同,比较函数返回0;如果第一项的值小于第二项,则返回负数。qsort()函数根据给定的其他信息计算出两个指针的值,然后把他们传递给比较函数。
qsort()函数原型中的第四个参数确定了比较函数的形式:

int (*compar)(const void *,const void *)

这表明qsort()函数最后一参数是一个指向函数的指针,该函数返回一个int类型的值并且接受两个指向const void的指针作为参数,这两个指针指向待比较项。
以下程序为利用系统随机数产生一个40的数组,快速排序后输出。
程序示例

#include
#include

#define NUM 40
void fillarray(double ar[], int n);
void showarray(const double ar[], int n);
int mycomp(const void *p1, const void *p2);

int main()
{
    double vals[NUM];
    fillarray(vals, NUM);
    puts("Random list:");
    showarray(vals, NUM);
    qsort(vals, NUM, sizeof(double), mycomp);
    puts("\n Sorted list:");
    showarray(vals, NUM);

    return 0;
}

//随机数,数组赋值
void fillarray(double ar[], int n)
{
    int index;

    for (index = 0; index < n; index++)
        ar[index] = (double)rand() / ((double)rand() + 0.1);
}

//显示数组
void showarray(const double ar[], int n)
{
    int index;

    for (index = 0; index < n; index++)
    {
        printf("%9.4f ", ar[index]);
        if (index % 6 == 5)
            putchar('\n');
    }
    if (index % 6 != 0)
        putchar('\n');
}

//从小到大排序
int mycomp(const void *p1, const void *p2)
{
    //要使用指向double的指针来访问这两个值
    const double *a1 = (const double *)p1;
    const double *a2 = (const double *)p2;

    if (*a1 < *a2)
        return -1;
    else if (*a1 == *a2)
        return 0;
    else
        return 1;
}

你可能感兴趣的:(16.8 快速排序之qsort()函数)