- ベストアンサー
構造体配列の安定なソート
- C言語で構造体配列を安定なソートする方法を知りたいです。
- バブルソートではなく、構造体の中の一つの要素をキーにしたソート方法を教えてください。
- ソート対象はint型の要素のみで、上限は100程度なので、速度的な問題は考慮しなくても大丈夫です。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>構造体のメンバを引数に渡すにはどうすればいいかとか、 >bubble_sort(&table[0].score, 10); bubble_sort(&table[0], 10) とすればいいと思います。 >メンバの配列を比較してメンバの順番だけ入れ替えたら、 >名前と得点の対応が壊れるから、 構造体自体は、出席番号と得点を保持しているのだから、 出席番号から名前が引き出せるのであれば、対応をとる必要はないと思うのですが、構造体の配列の並びがどっか別にある名前テーブル(配列?)と対応しているということであれば、名前テーブルも並び替える必要があるのかなぁとか思いますが、そんな必要はないような気がします。 なんか、どういうデータ構造になっているかよくわからないので、勘違いしてたらすみませんです。 できたら、バブルソート版のプログラムを補足していただけますか?
その他の回答 (3)
- moritan2
- ベストアンサー率25% (168/670)
単純ミスじゃないでしょうか? if((u->score - u->score)!=0) これは if((u->score - v->score)!=0) でしょう?
お礼
そこは間違いでした。 ありがとうございます。 ただやはりこの方法だとできないみたいです。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>int配列のバブルソートは出来た のであれば、 比較する値を構造体のメンバの得点にして、 交換するのを構造体(値型だから)にするか、それぞれの、メンバを交換すればいいだけです。
補足
すいませんが、 具体的にどのように変更すればいいのかが わからない状態です。 構造体のメンバを引数に渡すにはどうすればいいかとか、 bubble_sort(&table[0].score, 10); 配列の先頭要素を渡すということはこういうことなのか、それともこうなのか。 bubble_sort(&table[i].score, 10); 関数側のほうにも修正が必要なのかとか。 メンバの配列を比較してメンバの順番だけ入れ替えたら、 名前と得点の対応が壊れるから、 そうすると、最初に構造体のメンバだけでなく、 構造体配列そのものも渡して、関数の中でどうにかするということなんでしょうか。 そうするとやはり元の関数自体も変更する必要がありますよね。
- a-saitoh
- ベストアンサー率30% (524/1722)
比較関数を,「得点を比較するが,得点が同じで場合は出席番号で代償をきめる」というものにすれば,クイックソートでも大丈夫では?
補足
ありがとうございます。 元々の、比較関数は int _cdecl cmp(const void *a, const void *b) { struct scoretable *u, *v; u = (struct scoretable *)a; v = (struct scoretable *)b; return u->score - v->score; } のようになってるんですが、これを、 int _cdecl cmp(const void *a, const void *b) { struct scoretable *u, *v; u = (struct scoretable *)a; v = (struct scoretable *)b; if((u->score - u->score)!=0) { return u->score - v->score; } else { return u->no - v->no; } } のようにかえたのでは駄目でした。 多分これでは間違いなのだと思うのですが、 具体的にどのように変えればいいのでしょうか。
お礼
アドバイスが役に立ちなんとかできました。 ありがとうございました。 void swap(struct scoretable *ptr1, struct scoretable *ptr2) { struct scoretable w; w = *ptr1; *ptr1 = *ptr2; *ptr2 = w; } void bubble_sort(struct scoretable *ptr, int n) { int i, j; for(i=0; i<n-1; i++) { for(j=n-1; j>i; j--) { if(ptr[j-1].score > ptr[j].score) { swap(&ptr[j-1], &ptr[j]); } } } }
補足
ありがとうございます。 >bubble_sort(&table[0], 10) >とすればいいと思います。 渡すのは構造体で、関数内でメンバにアクセスするということですか。qsortでもそうでした。 これだと関数を書き換えないと駄目ですよね。 バブルソート版のプログラムは、 http://homepage1.nifty.com/daccho/program/algo/sort3.htm です。 void swap(int *ptr1, int *ptr2) { int w; w = *ptr1; *ptr1 = *ptr2; *ptr2 = w; } void bubble_sort(struct scoretable *ptr, int n) { int i, j; for(i=0; i<n-1; i++){ for(j=n-1; j>i; j--){ if(*((ptr->score)+j-1) > *((ptr->score)+j)){ swap(((ptr->score)+j-1), ((ptr->score)+j)); } } } } bubble_sort()の引数の型を書き換えて、 メンバにアロー演算子でアクセスするようにしただけで、 間接指定演算子 (*) の使い方が不正です。 'swap' : 1 番目の引数を 'int' から 'int *' に変換できません。 などのエラーが出ています。 ポインタを理解していない状態なので、多分今は理解しようとしても理解できないと思います。 それは後で本を読んで勉強するとして、 とりあえず今は動くようになればいいのですが。 構造体は普通の構造体で、メンバとして出席番号と得点があるで 問題ないです。対応が壊れるというのは、構造体の仕組みを勘違いしていました。