• 締切済み

C言語のクイックソートのプログラムについて

こんにちは。 この質問のページを開いて頂き、ありがとうございます。 よろしければ、力になってください(..) C言語を独学で勉強しているのですが、 クイックソートのプログラムでひっかかり 次に進めない状況となっております。(>_<) 力をお貸しください..... あまり、ポインタ変数とか得意ではないので、分かりやすい説明を頂けましたら これからの勉強とかにも生かせると思うのでよろしくお願いします。 編集点だけでも教えて頂ければ幸いです。 プログラムの内容としては data1.txtの内容を読み込み、その内容を生年月日順に並び替えるというプログラムです。 若い人が一番上に来るように(つまり、生年月日の降順?で)作らなければなりません。 それに加えて、どのパターンを読み込んだかの順番も表示しなければなりません。 上記の日本語が分かりにくかったらすいません。 説明下手でもあるので(..) ちなみにdata1.txtの内容は 名前 身長 靴のサイズ 生年月日 となっております。 -----------data1.txtの内容------- A 164 24.0 19770926 B 168 24.5 19750801 C 166 24.0 19780228 D 162 23.0 19850914 E 172 24.5 19780904 F 168 24.5 19770605 G 164 24.0 19790621 H 156 23.0 19900919 I 160 24.5 19860330 J 170 26.0 19680614 --------data1.txtの内容 終わり------------ --------------------以下 C言語プログラム------------------- #include <stdio.h> #include <stdlib.h> /* 自己参照的構造体テンプレートの宣言 */ typedef struct node{ char name[25]; double shincyo; double shoe_size; int birth; struct node *next; }node_t; /* ノード割り当て関数 */ node_t *NodeAllocate(void) { node_t *p = (node_t *)malloc(sizeof(node_t)); /* (B)動的メモリ割り当て */ if(p == NULL){ fprintf(stderr,"\nERROR: Out of memory\n"); exit(1); } return p; } int main(void) { FILE *fpin; char fname[20] = "data1.txt"; int i, count = 0; int max; //最大値をチェックするための変数 int shoecount=0; double shoesize; /*靴サイズ入力・検索に用いる*/ node_t *start, *p, *pre_p, *q, *s, *temp; start = p = NodeAllocate(); /* (A)出力開始点初期化&動的メモリ割り当て */ /* 読み出しファイルオープン */ if((fpin = fopen(fname, "r")) == NULL){ printf("ファイルのオープンに失敗しました\n"); exit(1); } while(1){ /* End of File を読んだら while の無限ループを脱出 */ if(feof(fpin)) break; else{ /* 1行ずつ書式を指定して読み出す */ fscanf(fpin, "%s%lf%lf%d\n", p->name, &(p->shincyo), &(p->shoe_size), &(p->birth)); p->next = NodeAllocate(); /* (C)動的メモリ割り当て&リンク */ pre_p = p; p = p->next; /* (D)リンクポインタの更新 */ } } /* 読み出しファイルクローズ */ fclose(fpin); /* 読み込み結果出力 */ pre_p->next = NULL; printf("\n******* 入力データ画面の表示 *******\n"); for(p = start;p != NULL;p = p->next) printf("%s %3.1f %2.1f %d\n", p->name, p->shincyo, p->shoe_size, p->birth); printf("************************************\n\n"); /* 並び替え処理(選択法でソート) */ for(p=start; p->next!=NULL; p=p->next) { max = p->birth; s = p; for(q=p->next;q!=NULL;q=q->next) { count++; if(max < q->birth) { max = q->birth; s = q; } } if(p == start && s == p->next){ /*パターン1*/ temp = s->next; s->next = p; p->next = temp; start = s; p = s; pre_p = p; printf("パターン1-->"); } else if(p == start && s != p->next && s != p){ /*パターン2*/ temp = s->next; s->next = p; p->next = temp; start = s; p = s; pre_p = p; printf("パターン2-->"); } else if(p != start && s == p->next){ /*パターン3*/ temp = s->next; s->next = p; p->next = temp; p = s; pre_p = p; printf("パターン3-->"); } else if(p != start && s != p->next && s != p){ /*パターン4*/ temp = s->next; s->next = p; p->next = temp; p = s; pre_p = p; printf("パターン4-->"); } else{ /*パターン5*/ temp = s->next; s->next = p; p->next = temp; printf("パターン5-->"); } } printf("END"); /* 並び替え処理の結果出力 */ printf("\n******* 並び替え後のデータの表示 *******\n"); for(p = start;p != NULL;p = p->next) printf("%s %3.1f %2.1f %d\n", p->name, p->shincyo, p->shoe_size, p->birth); printf("************************************\n\n"); return 0; } ---------------------C言語プログラムの内容 終わり----------------- 私が間違っていると思っているのは パターン2とパターン4の条件文のとこが間違っているのかな?と思いますが・・・ 他にも間違っていてそれが原因であるならそこの点も教えてください。(>_<) よろしかったら 間違い部分の修正、説明 などよろしくお願いしたします。m(_ _)m

みんなの回答

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.4

素朴な話として、今回のデータを扱う上で、リスト構造を採用する必要って そもそもあったんでしょうか。

  • k_kota
  • ベストアンサー率19% (434/2186)
回答No.3

ポインタはつまずき易いとこですね。 メモリの仕組みとかを軽くやって、よいサイトを探してみてください。 ポインタ出来ないとCができるとは言えないですね、まあポインタできてもCできるとは限らないですけど。 とりあえず、ソースがクイックになってないそうですので、 まずトランプでも何でもいいので自分でクイックソートをやってみてください。 次に、それをフローチャートで無くてもいいので自分で分かるように言葉にして下さい。 それを、プログラムにして下さい。 いきなりプログラムを書きがちですけど、最初は紙で考えたほうがいいです。 先にコメント書いてしまって、あとから実態を作るとかもいいかもしれません。 ちなみに、勉強する気が無いならコピペでいいと思いますけど、 ちゃんとやりたいなら上記の内容がそれなりに有効だと思います。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

> /* 並び替え処理(選択法でソート) */ ってあるし、ざっと追い掛けても、まったくクイックソートになっていません。(選択法はクイックソートでは無い) あと、ソートのアルゴリズムにはいろんな特性があるのはご存知かと思います。 このプログラムでデータ記憶に使っている「単方向リスト」に対しては、クイックソートの「速くなるしくみ」が有効に働かないので、効率が悪くなります。 # リストに対しては、自然マージソートが、効率よくて、プログラムも簡単です。 まずは、ソートのプログラムの基礎を勉強、ということで、intの配列をソートするプログラムから始めてはどうでしょう? int birth[]={19770926,19750801, 19780228,19850914,19780904,19770605,19790621,19900919,19860330,19680614} ; とでもして。質問にある課題はいったん忘れて。 intから別の型や構造体等に変わったら、「大小関係の求め方」と「入れ替え操作」に注意すれば、枠組みは一緒です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

うん, 「困っている」ことしかわからないという, よくある質問だね. 「パターン」が何かわからんし, いったいどこがクイックソートなのかもわからん. そして, 「『困っている』ことしかわからない」質問でよくあることなんだけど, あなたが何を問題にしているのかがさっぱりわからん.

関連するQ&A

専門家に質問してみよう