C — 快排函数 qsort 的用法

快排函数参数说明

qsort(s,n,sizeof(s[0]),cmp)

s 须要排序的数组名
n 数组中元素的个数
sizeof() 返回一个元素的 size
cmp 比较函数,具体见下文数组

比较函数

典型的比较函数定义是函数

int cmp(const void *a,const void *b)

其中,函数名 cmp 和参数名 a, b 都是能够自定义的,但类型必须是 const void * 型。
函数返回值必须是 int 型,若是须要结尾为升序,则在 a > b 的状况下返回正值,反之返回负值。
例如最多见的对 int 数组进行排序的比较函数写法以下:code

int cmp(const void *a, const void *b) {
    return (*(int *) a - *(int *) b);
}

对于 double 数组而言,因为两个 double 类型数不能直接判断相等,所以咱们能够处理为只返回 1 和 -1,或者增长其余判断语句来返回0的状况,这里咱们简单的做只返回 -1 和 1 做为例子:排序

int cmp(const void *a, const void *b) {
    return ((*(double *) a - *(double *) b > 0) ? 1 : -1);
}

那么当须要对二维数组排序时,能够用以下代码实现,也能够直接定义为结构体,推荐后者。本代码中,若是第一维值相等,则继续比较第二维的大小,能够根据实际状况修改。源码

int cmp(const void *a,const void *b)
{
    int *c = (int *)a;
    int *d = (int *)b;
    if(*c != *d)
        return *c - *d;
    return *(c+1) - *(d+1);
}

完整示例源码

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

int s[10000], n, i;

int cmp(const void *a, const void *b) {
    return (*(int *) a - *(int *) b);
}

int main() {
    scanf("%d", &n);
    for (i = 0; i < n; i++) scanf("%d", &s[i]);

    qsort(s, n, sizeof(s[0]), cmp);

    for (i = 0; i < n; i++) printf("%d ", s[i]);

    return (0);
}

快排函数实现源码

void qsort(int a[], int low, int high) {
    if (low >= high) {
        return;
    }
    int first = low;
    int last = high;
    int key = a[first]; // 用字表的第一个记录做为枢轴

    while (first < last) {
        while (first < last && a[last] >= key) {
            --last;
        }

        a[first] = a[last]; // 将比第一个小的移到低端

        while (first < last && a[first] <= key) {
            ++first;
        }

        a[last] = a[first]; // 将比第一个大的移到高端

    }
    a[first] = key; // 枢轴记录到位
    qsort(a, low, first - 1);
    qsort(a, first + 1, high);
}

快排的不稳定性

  1. 快排是不稳定的,这个不稳定一个表如今其使用的时间是不肯定的,最好状况 (O(n)) 和最
    坏状况 (O(n^2)) 差距太大,咱们通常说的 O(n·log(n)) 都是指的是其平均时间.io

  2. 快排是不稳定的,这个不稳定表如今若是相同的比较元素,可能顺序不同,假设咱们有
    这样一个序列 3, 3, 3 可是这三个3是有区别的,咱们标记为 3a, 3b, 3c 快排后的结果不必定就是 3a, 3b, 3c 这样的排列,因此在某些特定场合咱们要用结构体来使其稳定。ast

关于快排的技巧

  1. 快排 qsort() 的第三个参数,推荐使用sizeof(s[0]),特别是对结构体,
    每每本身定义 2 * sizeof(int) 可能会出问题,用 sizeof(s[0]) 既方便又保险。技巧

  2. 若是要对数组进行部分排序,好比对一个 s[n] 的数组排列其从 s[i] 开始的 m 个元素,只须要
    在第一个和第二个参数上进行一些修改,例如 qsort(&s[i], m, sizeof(s[i]), cmp)sort

相关文章
相关标签/搜索