構造体のメンバを基準にソートする方法

このQ&Aのポイント
  • 動的に割り当てた構造体のメンバを基準に降順や昇順にソートする方法を教えてください。
  • たとえば、商品価格を基準に並び替える機能を追加したい場合、どのように解決すれば良いでしょうか?
  • 構造体のメンバを利用して、ソート機能を追加する方法について教えてください。
回答を見る
  • ベストアンサー

構造体のあるメンバを基準にソートするには?

以下のように定義した構造体(下の構造体は入れ子になっている)を必要な時に動的に割り当てた後(デー多数は不定)、たとえば、商品価格を基準に降順、昇順に並び替える機能を追加したいのですが、どのように解決したらよろしいでしょうか? /* 現在の日時を格納する構造体 */ typedef struct time_type{ int year; int month; int day; }time_type; /* 商品の情報を格納する構造体 */ typedef struct shohin_type{ int code; /* 商品コード */ int price; /* 商品価格 */ char *name; /* 商品名 */ int flag; /* フラグ */ struct time_type date; /* 登録日 */ struct shohin_type *before; /* 前の構造体のアドレス */ struct shohin_type *next; /* 次の構造体のアドレス */ }shohin_type;

質問者が選んだベストアンサー

  • ベストアンサー
  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

クイックソートもどきのコーディングをしてみました。 考え方としては、データをある基準より前に来るものと後に来るものに 分けた上で、それぞれについて再帰的に同様の処理をします。 コンパイルも実行もしていませんので、「自信なし」としておきます。 なお、昇順のみです。降順への拡張はご自身で考えてみて下さい。  void sort(struct shohin_type **first, struct shohin_type **last)  {   struct shohin_type *datum = *first;   struct shohin_type *candidate;   struct shohin_type *next;   if (datum)   {    candidate = datum->next;    while (candidate && (cadidate != *last))    {     next = candidate->next;     if (datum->price > cadidate->price)     {      if (candidate->before)      {       candidate->before->next = candidate->next;      }      if (candidate->next)      {       candidate->next->before = candidate->before;      }      if (datum->before)      {       datum->before->next = candidate;      }      candidate->before = datum->before;      datum->before = candidate;      candidate->next = datum;     }    }    sort(first, &datum->before);    sort(&daum->next, last);   }  }

kiroro302
質問者

お礼

ranxさん、ご回答どうもありがとうございました。お礼が遅くなり大変申し訳ございません。これは商品管理プログラムで、商品の登録、更新、削除、検索、ソート、復旧(削除したものをもどす。)等の機能があり、登録したものをソートするのにどうすればよいのか悩んでおりました。ややこしいですが、なんとなくわかったようなわからないようなあやふやな感じなので、教えていただいた、ソースを参考に昇順にソートする関数を作ってみました。これを元に降順関数を作成してみます。ご指導ありがとうございました。またよろしくお願いいたします。

その他の回答 (1)

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.2

やっぱり「自信なし」で正解だったな。 ループの最後に抜けがありました。  candidate = candidate->next;

関連するQ&A

  • ファイルから読みこんで構造体に格納する、

    shohinというファイルに RX-100 odango_tsumeawase 3000という のが 五行ならんでいるのですが、 これを読み込んで struct shohin{ char code[10]: char name[40]; int price; } にファイルから読みこんで構造体配列に 格納したいのですが、構造体配列に格納する やりかたがわかりません。 構造体配列は struct shohin list[];というのを宣言しています。 ファイルから一行読み込んで fprintf()を使おうと思うのですが、 それはできますか? メンバ毎に格納したいのですが、 それがわかりません お願いします。

  • 入れ子の構造体について

    例えば、入れ子の構造体を1つ使いたい場合、 struct bbb{ int b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; と書くと、「dt.a.b = 10」とやれば、値等を設定できると思いますが、 入れ子の構造体を2つ使いたい場合も、同じように書けるのでしょうか? struct ccc{ int c; }; struct bbb{ struct ccc b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; dt.a.b.c = 10; と書けるのでしょうか?こんがらがってしまって、どう書いていいのか・・。 2つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 構造体メンバ 構造体ポインタ 値代入

    typedef struct _test_t{ int aaa; int bbb; } test_t; typedef struct _globalData{ int xxx; test_t* pTestData[256]; } globalData_t; globalData_t globalData; int main(){ test_t testData1 = {1,1}; test_t testData2 = {2,2}; *globalData.pTestData[1] = testData1; /* (1) */ globalData.pTestData[2] = &testData1; /* (2) */ } 上記のようなグローバルデータの構造体globalData のメンバの構造体配列にtest_t型の構造体を格納し保持するには、 (1)、(2)のどちらが正しいでしょうか?

  • 構造体の入れ子が構造体の場合のextern宣言について

    えーと、題名の通りで、単に構造体の場合はextern出来たのですが、構造体の入れ子が構造体の場合は上手くextern出来ないのです;;; typedef struct __test001 { int arg; } _test001; typedef struct _body { _test001 test001; } body; body useful; この場合、他のファイル(例えばtest.cpp)でusefulを使いたい場合、どのようにexternさせれば宜しいでしょうか?

  • 構造体の返し方

    こういう構造体があるとして、 typedef struct Day{  int day1, day2, day3; } Day; このような関数で値を入れて、 int DayTest (char s) {  Day day;  day1 = 2003;  day2 = 12;  dat3 = 31;  return < ここの返し方がわからない >; } これを main() 関数で参照できるようにするには どうすればいいのでしょうか。 printf で出力させるとかで結構です。 ポインタだとは思うのですが、うまくいきません。

  • 構造体の中の構造体

    typedef struct number{ int x; struct number *next; }Num; 初心者な質問で申し訳ないんですが、構造体の中に構造体があるのはどう解釈していいんでしょうか? typedef struct number{ int x; int y; }Num; の場合はNum a,b;がint a.x,a.y,b.x,b.yとなるのは分かるんですが・・・

  • 構造体メンバへの代入

    とても初歩的なことなのですが、 typedef struct _X{ int x; }X[50]; と構造体を定義して X[0].x = 0; と0を代入しようとすると、「宣言が正しく終了していない」とエラーが出てしまいます。 これはなぜでしょうか? ちなみにMicrosoft Visual C++ 2005 Express Editionを使っています。

  • 構造体のリストをソートしたい。

    ある名簿のリストを作りました。 以下のような構造体で、 typedef struct meibo{ char name[10]; int old; struct meibo *next; }MEIBO; これを、ポインタp->next->nameをたどっていって、名前が辞書順になるようにリストを作ったのですが、 これを年齢順にソートして表示させたいんです。 どんな方法があるんでしょうか? 一旦すべてを配列に格納して、クイックソート…とかも考えたのですが、すごく領域をとるし、なんか2度手間(最初から配列に順に格納していけばよかったなぁ・・・と。 それでもやっぱり最初から名列順にするときから配列に入れておくほうがいいのでしょうか? 教えてください。 (最初から年齢を比較してリストを作れば・・ってのはなしで、名列順のリストが存在するものとしてください。)

  • 構造体のtypedef宣言

    下の二種類の宣言は、同じ意味でしょうか? 同じ意味だとしたら、なぜこのような2通りの記述方法があるのでしょうか? typedef struct _TIME{ int hour; int min; } TIME; typedef struct { int hour; int min; } TIME;

  • 構造体について

    構造体についての質問です。 main関数で構造体に 格納しています。 その構造体の値を 自作の関数(look)で 参照したいのですが どのようにすればいいのか ご教示して頂けたら幸いです。 typedef struct nentbl_ { int tosi; int kan; } nentbl; //--------------------------------------------------- int look(id){ nentbl kihokyu[50]; printf("%d %d\n",kihokyu[id].tosi , kihokyu[id].kan); } //---------------------------------------------------- int main(void){ nentbl kihokyu[50]; ・ ・ ・ kihokyu[1].tosi =11; kihokyu[1].kan = 20; kihokyu[2].tosi = 21; kihokyu[2].kan = 30; kihokyu[3].tosi = 31; kihokyu[3].kan = 40; y = look(1);

専門家に質問してみよう