今回は、構造体そのものの配列でなく、構造体を指すポインタの配列を qsort するプログラム例です。
以前の Tips で「構造体配列の qsort」を扱いましたが、構造体のサイズが大きくて配列要素もたくさんあるときは、構造体配列の各要素を指すポインタの配列を作ってソートする方が効率的です。
ポインタ配列を用意するひと手間がありますが、かさばる構造体を並べ替えるより、効率よく処理することができます。
下記では、卒業論文のデータを入れた構造体配列をソートする例を示します。
#include <stdio.h> #include <stdlib.h> #define NDATA ((sizeof lst)/(sizeof(ronbun_t))) typedef struct { int id; //ID int year; //年度 int hk; //評価点 char *title; //論文タイトル } ronbun_t; // --------------- 比較用の関数 cmp ------------------- int cmpptr( const void *p, const void *q ) { return (*(ronbun_t**)p)->id - (*(ronbun_t**)q)->id; } // ---------------------------------------------------- main() { ronbun_t lst[] = { {45,2011,99,"貿易と産業"}, {89,2011,99,"アニメに見る社会"} , {73,1999,98,"なぜ人は山に登るか"},{33,2011,98,"邦画と洋画考察"} , {64,2003,97,"世界進出するには"}, {21,2013,96,"ゲームと戦略"} , {72,2006,96,"ハリウッドの変遷"}, { 3,2009,95,"製造業の未来"} , {30,2013,95,"金融政策について"}, { 9,2003,94,"原価計算の研究"} , {87,2011,94,"デザインの多様性"}, {99,2008,93,"OJTの効果"} , {51,2002,92,"緑の地球を取り戻す"},{34,2009,91,"似合う色とは"} , {66,2004,91,"待ち行列について"}, {26,2012,90,"ネット依存心理"} , {11,1995,90,"職人技とは"}, {18,2008,90,"ディズニーの戦略"} }; int i; ronbun_t *plst[NDATA]; // ポインタの配列 plst に構造体配列のアドレスを代入 for( i = 0; i < NDATA; i++ ) plst[i] = &lst[i]; // id順にソート qsort( plst, NDATA, sizeof(ronbun_t*), cmpptr ); // 並べ替え後の内容を表示 printf( "ID, 年度, タイトル(評価点)\n" ); for( i = 0; i < NDATA; i++ ) printf( "%2d, %d, %s(%d)\n" , plst[i]->id, plst[i]->year, plst[i]->title, plst[i]->hk ); }実行結果
ID, 年度, タイトル(評価点) 3, 2009, 製造業の未来(95) 9, 2003, 原価計算の研究(94) 11, 1995, 職人技とは(90) 18, 2008, ディズニーの戦略(90) :途中略 99, 2008, OJTの効果(93)plst は ID順になるようポインタが並べ替えられますが、元の構造体配列 lst は、元のままです。
qsort( plst, NDATA, sizeof(ronbun_t*), cmpptr );plst には plst[i] = &lst[i]; で構造体配列の各要素のアドレスを設定済みです。
return (*(ronbun_t**)p)->id - (*(ronbun_t**)q)->id;
[ 関連記事 ] int配列をqsort, 構造体配列をqsort
[ ご案内 ] 要点を学習できるコース:要点講座 [配列とポインタ編]/[構造体編]