ホームC言語Tips集配列・メモリ領域 ≫ 配列やメモリ領域の内容を整列(sort)する

C言語Tips集 - 配列やメモリ領域の内容を整列(sort)する

C言語で配列やメモリ領域の内容を整列 (sort) するには stdlib.hqsort 関数を使用します.

qsort

#include <stdlib.h>
void qsort (
    void *base,
    size_t nmemb,
    size_t size,
    int (*compar)(const void *, const void *)
);

qsort 関数は,base が指すオブジェクトの配列 (要素数が nmemb 個,各要素の大きさが size である配列) を compar が指す比較関数にしたがって整列する関数です.ちなみに qsort 関数の名前はクイックソート (quick sort) に由来しますが,内部でクイックソートアルゴリズムを使用してる保障はありません.(処理系定義)

qsort 関数の引数をまとめると以下のようになります.

引数

  • base: 整列したい配列
  • nmemb: 配列の要素数
  • size: 配列の個々の要素のサイズ
  • compar: 比較関数

比較関数

qsort 関数を使用するには,事前にプログラマが比較関数 (compar) を実装しておく必要があります.比較関数は以下のルールに基づいて実装する必要があります.

  • 第 1 引数が第 2 引数より小さい場合: 0 より小さい値を返す
  • 第 1 引数が第 2 引数と一致する場合: 0 を返す
  • 第 1 引数が第 2 引数よりも大きい場合: 0 より大きい値を返す

C言語サンプルプログラム

以下に qsort 関数を使用して int 型の配列を昇順に整列するサンプルプログラムを示します.

/* header files */
#include <stdio.h>
#include <stdlib.h>

/* functions */
int compar(const int *val1, const int *val2);

/* main */
int main(void) {
    int ary[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
    int n = sizeof(ary) / sizeof(ary[0]);
    int i;

    /* 配列の内容を表示 */
    printf("整列前: ");
    for ( i = 0; i < n; i++ ) {
        printf("%d", ary[i]);
    }

    /* qsort 関数を使用して昇順に並び替える */
    qsort(ary, n, sizeof(int),
        (int (*)(const void *, const void *))compar
    );

    /* 配列の内容を表示 */
    printf("\n整列後: ");
    for ( i = 0; i < n; i++ ) {
        printf("%d", ary[i]);
    }
    printf("\n");

    return EXIT_SUCCESS;
}

/**
 * 比較関数
 */
int compar(const int *val1, const int *val2) {
    if ( *val1 < *val2 ) {
        return -1;
    } else if ( *val1 == * val2 ) {
        return 0;
    } else {
        return 1;
    }
}

実行例

サンプルプログラムの実行結果は以下のようになります.

整列前: 987654321
整列後: 123456789

Cプログラマの必読書

たくさんあるC言語関連の書籍の中でも特に役に立った本です.よかったら参考にしてみてください.

C実践プログラミング 第3版

C言語の実践的参考書.少々値段は張りますが初心者を脱しようとしている人は絶対に読むべきです.
文法だけでなく,コーディングスタイルやデバッグなど文字通り「実践的」なことが書かれているので非常にためになります. オライリーの本は,読みにくい本が多いのですが本書はとても読みやすくオススメです.


C言語ポインタ完全制覇 (標準プログラマーズライブラリ)

ポインタの解説書としては最高の書籍です.
この1冊でポインタを完全に理解することができます.全くの初学者が読むには敷居が高いですが,入門書を読み終えた後に読むと非常に有益です.

整列・探索