■整数配列のソート
●第1引数 ソート対象の配列
int 配列[] = { 3,1,4,1,5,9,2,6,5,3 };
●第2引数 配列の要素数
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
●第3引数 配列1個のサイズ
●第4引数 比較関数
int 比較関数(const void *p1, const void *p2) {
int n1 = *(const int *)p1;
int n2 = *(const int *)p2;
return n1 - n2;
}
●整数編qsort使用例
#include <stdio.h>
#include <stdlib.h>
int 比較関数(const void *p1, const void *p2) {
int n1 = *(const int *)p1;
int n2 = *(const int *)p2;
return n1 - n2;
}
int main(void){
int 配列[] = { 3,1,4,1,5,9,2,6,5,3 };
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
for (size_t i = 0 ; i < 要素数 ; i++)
printf("ソート前△:%d\n", 配列[i]);
qsort(配列,要素数,sizeof(配列[0]),比較関数);//整数ソート
for (size_t i = 0 ; i < 要素数 ; i++)
printf("ソート後▼:%d\n", 配列[i]);
}
n1 – n2の引き算の結果で
数値順にソートします。
●qsort実行結果
./a.out
ソート前△:3
ソート前△:1
ソート前△:4
ソート前△:1
ソート前△:5
ソート前△:9
ソート前△:2
ソート前△:6
ソート前△:5
ソート前△:3
ソート後▼:1
ソート後▼:1
ソート後▼:2
ソート後▼:3
ソート後▼:3
ソート後▼:4
ソート後▼:5
ソート後▼:5
ソート後▼:6
ソート後▼:9
■文字列配列のソート
●第1引数:ソート対象の配列
const char *配列[]={
"moshi",
"moshi",
"kame",
"yo",
"kamesan",
"yo",
"sekai",
"no",
"uchini"
};
■第2引数:配列の要素数
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
●第3引数:配列1個のサイズ
●第4引数:比較関数
int 比較関数(
const void *argv1,
const void *argv2)
{
const char *s1 = ((char *const*)argv1)[0];
const char *s2 = ((char *const*)argv2)[0];
return strcmp(s1,s2) ;
}
strcmp()で辞書並びにソートします。
●文字列編qsort使用例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int 比較関数(
const void *argv1,
const void *argv2)
{
const char *s1 = ((char *const*)argv1)[0];
const char *s2 = ((char *const*)argv2)[0];
return strcmp(s1,s2) ;
}
//文字列ソート
int main(void){
const char *配列[]={
"moshi",
"moshi",
"kame",
"yo",
"kamesan",
"yo",
"sekai",
"no",
"uchini"
};
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
for (size_t i=0 ; i < 要素数; i++)
printf("ソート前△:%s\n", 配列[i]);
qsort(配列,要素数,sizeof(配列[0]),比較関数);
for (size_t i=0 ; i < 要素数; i++)
printf("ソート後▼:%s\n", 配列[i]);
}
●文字列編実行結果
./a.out
ソート前△:moshi
ソート前△:moshi
ソート前△:kame
ソート前△:yo
ソート前△:kamesan
ソート前△:yo
ソート前△:sekai
ソート前△:no
ソート前△:uchini
ソート後▼:kame
ソート後▼:kamesan
ソート後▼:moshi
ソート後▼:moshi
ソート後▼:no
ソート後▼:sekai
ソート後▼:uchini
ソート後▼:yo
ソート後▼:yo
■構造体配列のソート
qsortのソートキーが複数ある場合の使い方
●第1引数 ソート対象の配列
typedef struct {
char 名前[128];
int 年齢;
char 郵便番号[128];
} 構造体枠_t ;
static 構造体枠_t 配列[]={
{.名前="佐藤",.年齢=98, .郵便番号="111-2345"},
{.名前="鈴木",.年齢=108, .郵便番号="222-3456"},
{.名前="田中",.年齢=88, .郵便番号="333-4567"},
{.名前="加藤",.年齢=78, .郵便番号="111-2345"},
{.名前="伊藤",.年齢=78, .郵便番号="333-4567"},
{.名前="武藤",.年齢=78, .郵便番号="222-3456"},
{.名前="須藤",.年齢=78, .郵便番号="111-2345"},
};
●第2引数 配列の要素数
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
●第3引数 配列1個のサイズ
●第4引数 qsort比較関数(複数条件)
int 比較関数(const void *p1, const void *p2){
//第1ソートキーを年齢とする
int n1 = ((const 構造体枠_t *)p1)->年齢;
int n2 = ((const 構造体枠_t *)p2)->年齢;
if(n1 != n2){
return n1 - n2;
}
//第2ソートキーを郵便番号とする
const char *s1 = ((const 構造体枠_t *)p1)->郵便番号;
const char *s2 = ((const 構造体枠_t *)p2)->郵便番号;
return strcmp(s1,s2);
}
第1ソートキーを年齢(若い順)
第2ソートキーを郵便番号(辞書並び)
としています。
●構造体編qsort使用例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char 名前[128];
int 年齢;
char 郵便番号[128];
} 構造体枠_t ;
static 構造体枠_t 配列[]={
{.名前="佐藤",.年齢=98, .郵便番号="111-2345"},
{.名前="鈴木",.年齢=108, .郵便番号="222-3456"},
{.名前="田中",.年齢=88, .郵便番号="333-4567"},
{.名前="加藤",.年齢=78, .郵便番号="111-2345"},
{.名前="伊藤",.年齢=78, .郵便番号="333-4567"},
{.名前="武藤",.年齢=78, .郵便番号="222-3456"},
{.名前="須藤",.年齢=78, .郵便番号="111-2345"},
};
int 比較関数(const void *p1, const void *p2){
//第1ソートキーを年齢とする
int n1 = ((const 構造体枠_t *)p1)->年齢;
int n2 = ((const 構造体枠_t *)p2)->年齢;
if(n1 != n2){
return n1 - n2;
}
//第2ソートキーを郵便番号とする
const char *s1 = ((const 構造体枠_t *)p1)->郵便番号;
const char *s2 = ((const 構造体枠_t *)p2)->郵便番号;
return strcmp(s1,s2);
}
void DMP(const char *mess,構造体枠_t ary[],size_t max){
for(size_t i = 0;i < max;i++) {
printf("%s:年齢=%-3d 〒=%s 名前=%s\n",
mess,
ary[i].年齢,
ary[i].郵便番号,
ary[i].名前
);
}
}
// 構造体ソート
int main(void){
size_t 要素数 = sizeof(配列) / sizeof(配列[0]) ;
DMP("ソート前△:",配列,要素数);
qsort(配列,要素数,sizeof(配列[0]),比較関数);
DMP("ソート後▼:",配列,要素数);
}
●構造体編実行結果
./a.out
ソート前△::年齢=98 〒=111-2345 名前=佐藤
ソート前△::年齢=108 〒=222-3456 名前=鈴木
ソート前△::年齢=88 〒=333-4567 名前=田中
ソート前△::年齢=78 〒=111-2345 名前=加藤
ソート前△::年齢=78 〒=333-4567 名前=伊藤
ソート前△::年齢=78 〒=222-3456 名前=武藤
ソート前△::年齢=78 〒=111-2345 名前=須藤
ソート後▼::年齢=78 〒=111-2345 名前=加藤
ソート後▼::年齢=78 〒=111-2345 名前=須藤
ソート後▼::年齢=78 〒=222-3456 名前=武藤
ソート後▼::年齢=78 〒=333-4567 名前=伊藤
ソート後▼::年齢=88 〒=333-4567 名前=田中
ソート後▼::年齢=98 〒=111-2345 名前=佐藤
ソート後▼::年齢=108 〒=222-3456 名前=鈴木