qsort を用いたソート

C言語の標準関数である、qsort() 関数を用いたソートの例です。qsort() 関数ではポインタの概念をバンバン使用しないといけないので、若干、頭がこんがらがるかもしれないですね。若干詳しくプログラムの詳細を説明していきましょう。

qsort を用いたソートlist_50.c)
#include <stdio.h>
#include <stdlib.h>

/*-------------------------------------------------------
 * compare 関数の規定:
 *   ソートの大小比較を規定。
 *   第1引致が第2引数より
 *          小さい/等しい/大きい とみなされるとき、
 *   それぞれ、
 *   0より 小さい/等しい/大きい
 *   整数を返すように指定。
 * -------------------------------------------------------*/
int c_compare( const void *x, const void *y){
    return strlen(*(char **)y) - strlen(*(char **)x);
}
int i_compare( const void *x, const void *y){
    return (**(int **)y - **(int **)x);
}
/* データの表示 */
void c_disp(int n,char** c_table)
{
    int i;
    for(i=0;i<n;i++){
        printf(" %d:%s\n",i,c_table[i]);
    }
}
void i_disp(int n,int** i_table)
{
    int i;
    for(i=0;i<n;i++){
        printf(" %d:%d\n",i,*i_table[i]);
    }
}

/* メインプログラム */
int main()
{
    char a[] = "orange";
    char b[] = "apple";
    char c[] = "melon";
    char *c_table[3];
    int i;
    int idata[5] = {20,15,5,10,8};
    int *i_table[5];
    
    /* 文字列のソート */
    printf("**文字列のソ\ート\n");
    c_table[0] = a;
    c_table[1] = b;
    c_table[2] = c;
    printf("ソ\ート前\n");
    c_disp(3,c_table);
    qsort(c_table,3,sizeof(char *),c_compare);
    printf("ソ\ート後\n");
    c_disp(3,c_table);

    /* 数値列のソート */
    printf("**数値列のソ\ート\n");
    for(i = 0; i<5; i++){
        i_table[i] = &idata[i];
    }
    printf("ソ\ート前\n");
    i_disp(5,i_table);
    qsort(&i_table[0],5,sizeof(int *),i_compare);
    printf("ソ\ート後\n");
    i_disp(5,i_table);
    
    return 0;
}


qsort の引数: void qsort(void * base, size_t nmemb, size_t size, int (* compar)(const void *, const void *) ); void* base : データ元となるデータを指し示すポインタ用配列 size_t nmemb: 配列の数 size_t size: データの型のサイズ(sizeof で指定) int (*compar)(const void*, const void*)): ソートで用いる大小比較用関数 プログラムの説明:  qsort() の関数内では、データ元となるデータ、もしくは配列を、それぞれポ インタで指し示し、ポインタが指し示すデータの順番を入れ替えていくことにな ります。  プログラム内では、 文字列のデータを指し示すポインタ用配列:char* c_table[3]; 数値列のデータを指し示すポインタ用配列: int* i_table[5]; のそれぞれのアドレスを c_table[0] = a; → 配列aの先頭アドレス i_table[i] = &idata[i]; → idata[]配列のi番目のデータのアドレス というように指定し、qsort() 関数が指し示されたアドレスの順番を入れ替えて いくことになります。 qsort() で指定する大小規定用の関数 compare() は、文字列、数値列用それぞ れに準備しています。ここでも、ポインタの扱いで悩む方も出てくるかもしれま せんね。compare() の関数は、2つのデータの大小を正負の値を使って表現する ような関数を自分で規定するものですが、今回は、単に文字列の長さと、データ の大きさで指定しています。 あとは、表示の部分を付け加えたのみです。
実行結果
Gami[143]% list_50.exe
**文字列のソート
ソート前
 0:orange
 1:apple
 2:melon
ソート後
 0:orange
 1:apple
 2:melon
**数値列のソート
ソート前
 0:20
 1:15
 2:5
 3:10
 4:8
ソート後
 0:20
 1:15
 2:10
 3:8
 4:5
Gami[144]%
inserted by FC2 system