質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

1回答

1581閲覧

リストのソートがうまくいきません

wagon

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/07/16 04:40

編集2018/07/16 06:25
コード ```### 前提・実現したいこと ノードを用いたソートの関数の実現 ### 発生している問題・エラーメッセージ 実行したところ、listの中身が一部取り除かれてしまいます

エラーメッセージ

### 該当のソースコード ```C言語 /*(ヘッダ部)*/ #ifndef MYNODE_H #define MYNODE_H #include<stdio.h> #include<stdlib.h> #include<string.h> /*--- 生徒データ ---*/ typedef struct { char name[20]; /* 氏名 */ int math; /*数学*/ int eng; /*英語*/ } Student; /*--- ノード ---*/ typedef struct __node { Student data; /* データ */ struct __node *next; /* 後続ポインタ(後続ノードへのポインタ)*/ } Node; /*--- 線形リスト ---*/ typedef struct { Node *head; /* 先頭ノードへのポインタ */ Node *crnt; /* 着目ノードへのポインタ */ } List; /*--- 線形リストを初期化 ---*/ void Initialize(List *list) { list->head = NULL; /* 先頭ノード */ list->crnt = NULL; /* 着目ノード */ } /*--- 一つのノードを動的に生成 ---*/ Node *AllocNode(void) { if(calloc(1,sizeof(Node)) == NULL) { puts("記憶域の確保に失敗しました"); return NULL; } else return calloc(1,sizeof(Node)); } /*--- nの指すノードの各メンバに値を設定 ----*/ void SetNode(Node *n, Student *x, Node *next) { n->data = *x; /* データ */ n->next = next; /* 後続ポインタ */ } /*--- 生徒データの表示(改行あり)---*/ void PrintLnStudent(const Student *x) { printf("Name:%s Math:%d Eng:%d\n", x->name, x->math, x->eng); } /*--- 先頭にノードを挿入 ---*/ void InsertFront(List *list, Student *x) { Node *ptr = list->head; list->head = list->crnt = AllocNode(); SetNode(list->head, x, ptr); } /*--- 全ノードのデータをリスト順に表示 ---*/ void Print(const List *list) { if (list->head == NULL) puts("ノードがありません。"); else { Node *ptr = list->head; puts("全データを先頭ノードから順番に表示する"); while (ptr != NULL) { PrintLnStudent(&ptr->data); ptr = ptr->next; /* 後続ノードに着目 */ } } } //ソートの関数 void math_sort(List *list) { int min,score; Student tmp; Node *phead = list->head; Node *ptr_i = list->head; Node *ptr_j; Node *ptr_min; while(ptr_i->next != NULL) { ptr_j = ptr_i; ptr_min = ptr_i; min = ptr_i->data.math; //最小値を探索 while(ptr_j->next != NULL) { ptr_j= ptr_j->next; score = ptr_j->data.math; if(min > score) { min = score; //着目ノードを変更 list->crnt = ptr_j; ptr_min = ptr_j; } } //最小値がptr_iにない場合 if(ptr_min != ptr_i) { tmp = ptr_min->data; RemoveCurrent(list); if(ptr_i == list->head) { InsertFront(list,&tmp); ptr_i = ptr_i->next; } else { phead = phead->next = ptr_i; ptr_i = ptr_i->next; phead->next = AllocNode(); SetNode(phead->next,&tmp,ptr_i); ptr_i = ptr_i->next; } } //最小値がptr_iにある場合 else { phead = phead->next; ptr_i = ptr_i->next; } } } #endif ソースファイル #include<stdio.h> #include"mynode.h" int main(void) { List list; Initialize(&list); fset_all_Student(&list,"input.txt"); Print(&list); math_sort(&list); Print(&list); return 0; }

試したこと

ファイルからの読み込みには成功していました。
実行結果はこのように表示されました
全データを先頭ノードから順番に表示する
Name:Tom Math:75 Eng:60
Name:Jerry Math:85 Eng:90
Name:Spike Math:45 Eng:30
Name:Rachel Math:55 Eng:85
Name:Monica Math:75 Eng:90
Name:Phoebe Math:80 Eng:75
Name:Chandler Math:70 Eng:65
Name:Joey Math:85 Eng:75
Name:Ross Math:90 Eng:85
全データを先頭ノードから順番に表示する
Name:Spike Math:45 Eng:30
Name:Tom Math:75 Eng:60
Name:Jerry Math:85 Eng:90
Name:Phoebe Math:80 Eng:75
Name:Chandler Math:70 Eng:65
Name:Joey Math:85 Eng:75
Name:Ross Math:90 Eng:85

上部分がファイルに入っているデータです。
下部分の表示でSpikeの次に先頭に表示したいものとその次の人のデータが消えてしまいます。
どのように修正すれば解決するでしょうか。

補足情報(FW/ツールのバージョンなど)

visual C++ 2010

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2018/07/16 04:52

うまくいかないのはノードの挿入ではなくリストのソートではないのか? であればタイトルの間違い。
y_waiwai

2018/07/16 05:10

コードがベタ書きになってるので修正してください。編集ボタンを押して、<code>を押して、'''の枠の中にコードをコピペしてくだされ
wagon

2018/07/16 06:26

修正させていただきました。すみません。
rubato6809

2018/07/17 04:26

RemoveCurrent() はどうなってますか? とりあえず、fset_all_Student()は書けました。
guest

回答1

0

C

1Node* minimum_node(Node* p) { 2 p, p->next, p->next->next ... の中から最小値を持つ Node* を返す 3} 4 5void swap_node(Node* x, Node* y) { 6 x->data と y->data を交換する 7}

を作っておけば

C

1void math_sort(List *list) { 2 Node* p = list->head; 3 while ( p != NULL ) { 4 // p以降の最小Nodeとpのナカミを交換 5 swap_node(p, minimun_node(p)); 6 p = p->next; 7 } 8}

でよくね?

投稿2018/07/16 05:32

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2018/07/16 05:45

こうすると Node *crnt; 不要。
wagon

2018/07/16 06:37

回答ありがとうございます。 しかしながら、今回は最小値を含むノードを削除して、そのノードを挿入していくという手順で行いたいんです。 すみません。
episteme

2018/07/16 11:05

えーと...ごめん、メンド臭いから僕はパス。
wagon

2018/07/16 11:32

了解です。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問