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

相關文章
相關標籤/搜索