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

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

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

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

Q&A

解決済

2回答

5894閲覧

構造体リストのメンバを比べてを昇順、降順ならびかえる

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

連結リスト

連結リストとは、データ構造のひとつであるリストの中で、要素が前後の要素の情報を持つことで、要素が連結(リンク)しているリストの事を呼びます。

0グッド

0クリップ

投稿2021/05/17 15:33

構造体のリストを並び替えたい。リストを並び替えるプログラムを作ったが、構造体メンバごとに昇順、降順に並び替えたい。

2:ソートを押下

名前 住所

昇順、降順

並び替え

といったプログラムにしたいです。
いまのプログラムは住所について並び直しています。
名前について並び直したいときは、もう一つソート関数のコードを書く以外の書き方がわかりません。構造体ポインタのメンバを引数にする?とか可能なのでしょうか?
また、降順についても、わかりやすい書き方がしたいです。

以下ソースコードになります。

#include <stdio.h> #include <string.h> #include <stdlib.h> #define NO_PROBLEM 0 #define ERROR 1 typedef struct student { int id; char name[10 + 1]; char address[10 + 1]; struct student *next; } PERSON_t; static PERSON_t *head = NULL; static PERSON_t *tail = NULL; int add_person(int id); int sort_person(void); void print_person(PERSON_t *p); PERSON_t * quick_sort(PERSON_t *a); int main(void) { int number = 0; int id = 0; while (1) { printf("1.追加入力 2.ソート 3.表示 0.終了: "); scanf("%d", &number); switch (number) { case 0: return 0; case 1: if (add_person(++id) == NO_PROBLEM){ puts("追加完了"); } break; case 2: head = quick_sort(head ); puts("並べ替え完了"); break; case 3: print_person(head); } } } PERSON_t * quick_sort(PERSON_t *a) { PERSON_t *pivot = a; //初めの文字をpivotとする a = head 基準 PERSON_t *less = NULL; //基準より小さい PERSON_t *greater = NULL; //基準より大きい PERSON_t *z; if (a == NULL || a->next == NULL){ //何もなかったらreturn puts("NULL"); return a; } puts("1"); a = a->next; pivot->next = NULL; while (a) { int diff; diff = strcmp(a->address, pivot->address); if (diff < 0){ z = a; a = a->next; z->next = less; less = z; } else if (diff > 0){ z = a; a = a->next; z->next = greater; greater = z; } else { z = a; a = a->next; z->next = pivot; pivot = z; } } less = quick_sort(less); greater = quick_sort(greater); if (less == NULL){ a = pivot; printf("基準%s",pivot); } else { for (a = z = less; z && z->next; z = z->next) ; z->next = pivot; } for (z = pivot; z->next; z = z->next) ; puts("8"); z->next = greater; return a; } int add_person(int id) { PERSON_t *data; data = (PERSON_t *)malloc(sizeof(PERSON_t)); data->id = id; printf("ID->%d\n", data->id); scanf("%10s", data->name); fflush(stdin); scanf("%10s", data->address); data->next = NULL; if (head == NULL) { head = data; tail = data; } else { tail->next = data; tail = data; } return NO_PROBLEM; } void print_person(PERSON_t *p) { for (; p; p = p->next){ printf(" %s", p->name); printf(" %s\n", p->address); } putchar('\n'); }

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

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

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

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

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

guest

回答2

0

比較関数を渡せばいいでしょう。

C

1#include <stdio.h> 2#include <string.h> 3#include <stdlib.h> 4 5#define NO_PROBLEM 0 6 7typedef struct student { 8 int id; 9 char name[10 + 1]; 10 char address[10 + 1]; 11 struct student *next; 12} PERSON_t; 13 14static PERSON_t *head = NULL; 15static PERSON_t *tail = NULL; 16 17int add_person(int id); 18void print_person(PERSON_t *p); 19PERSON_t * quick_sort(PERSON_t *a, int comp(PERSON_t *, PERSON_t *)); 20int compare_name(PERSON_t *a, PERSON_t *b); 21int compare_address(PERSON_t *a, PERSON_t *b); 22 23int main(void) 24{ 25 int number = 0; 26 int id = 0; 27 while (1) { 28 printf("1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: "); 29 scanf("%d", &number); 30 switch (number) { 31 case 0: 32 return 0; 33 case 1: 34 if (add_person(++id) == NO_PROBLEM)puts("追加完了"); 35 break; 36 case 2: 37 print_person(head); 38 break; 39 case 3: 40 head = quick_sort(head, compare_name); 41 puts("並べ替え完了"); 42 break; 43 case 4: 44 head = quick_sort(head, compare_address); 45 puts("並べ替え完了"); 46 break; 47 } 48 } 49} 50 51 52PERSON_t * quick_sort(PERSON_t *a, int comp(PERSON_t *, PERSON_t *)) 53{ 54 PERSON_t *pivot = a; //初めの文字をpivotとする a = head 基準 55 PERSON_t *less = NULL; //基準より小さい 56 PERSON_t *greater = NULL; //基準より大きい 57 PERSON_t *z; 58 if (a == NULL || a->next == NULL) return a; //要素数が 0 か 1 の時 59 60 a = a->next; 61 pivot->next = NULL; 62 while (a) { 63 z = a; 64 a = a->next; 65 int diff = comp(z, pivot); 66 if (diff < 0) { 67 z->next = less; 68 less = z; 69 } 70 else if (diff > 0) { 71 z->next = greater; 72 greater = z; 73 } 74 else { 75 z->next = pivot; 76 pivot = z; 77 } 78 } 79 less = quick_sort(less, comp); 80 greater = quick_sort(greater, comp); 81 82 if (less == NULL) a = pivot; 83 else { 84 for (a = z = less; z && z->next; z = z->next) ; 85 z->next = pivot; 86 } 87 for (z = pivot; z->next; z = z->next) ; 88 z->next = greater; 89 return a; 90} 91 92int add_person(int id) 93{ 94 PERSON_t *data; 95 data = (PERSON_t *)malloc(sizeof(PERSON_t)); 96 data->id = id; 97 printf("ID->%d\n", data->id); 98 scanf("%10s", data->name); 99 scanf("%10s", data->address); 100 101 data->next = NULL; 102 if (head == NULL) { 103 head = data; 104 tail = data; 105 } else { 106 tail->next = data; 107 tail = data; 108 } 109 return NO_PROBLEM; 110} 111 112void print_person(PERSON_t *p) 113{ 114 for (; p; p = p->next) printf(" %s %s\n", p->name, p->address); 115 putchar('\n'); 116} 117 118int compare_name(PERSON_t *a, PERSON_t *b) 119{ 120 return strcmp(a->name, b->name); 121} 122 123int compare_address(PERSON_t *a, PERSON_t *b) 124{ 125 return strcmp(a->address, b->address); 126} 127

実行例

1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 1 ccc tokyo ID->1 追加完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 1 aaa osaka ID->2 追加完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 1 ddd kyoto ID->3 追加完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 1 bbb nagoya ID->4 追加完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 2 ccc tokyo aaa osaka ddd kyoto bbb nagoya 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 3 並べ替え完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 2 aaa osaka bbb nagoya ccc tokyo ddd kyoto 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 4 並べ替え完了 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 2 ddd kyoto bbb nagoya aaa osaka ccc tokyo 1.追加入力 2.表示 3.名前でソート 4.住所でソート 0.終了: 0

この問題の出典は何ですか?

追記

また、降順についても、わかりやすい書き方がしたいです。

a と b を入れ替えて比較する関数を用意すればよいでしょう。

C

1int compare_name_rev(PERSON_t *a, PERSON_t *b) 2{ 3 return strcmp(b->name, a->name); 4}

投稿2021/05/17 18:24

編集2021/05/18 16:15
kazuma-s

総合スコア8224

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

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

0

ベストアンサー

diff = strcmp(a->address, pivot->address);

ここでaddressかnameかに分ければいいかと思います。

(元のコードを生かした書き方をします。日本語のところはご自身で適当な名前をつけてください。)

C

1PERSON_t * quick_sort(PERSON_t *a, int (ソート種別)); 2 3PERSON_t * quick_sort(PERSON_t *a, int (ソート種別)) 4{ 5 char *pPivot; // pivot用ポインタ 6 7(省略) 8 9 puts("1"); 10 a = a->next; 11 pivot->next = NULL; 12 /********追加コード*******/ 13 if ((ソート種別) == 住所) 14 { 15 pPivot = pPivot->address; 16 } 17 else // if ((ソート種別) == 名前) 18 { 19 pPivot = pPivot->name; 20 } 21 /********ここまで(追加コード)*******/ 22 while (a) { 23 int diff; 24 /********追加コード*******/ 25 char *pA; 26 if ((ソート種別)==住所) 27 { 28 pA = pivot->address; 29 } 30 else // if ((ソート種別) == 名前) 31 { 32 pA = pivot->name; 33 } 34 35 diff = strcmp(pA, pPivot); // diff = strcmp(a->address, pivot->address);から書き換え 36 /********ここまで(追加コード)*******/ 37 38 (以下略) 39

こんな感じでaddressとname、どちらかを示す中間ポインタを宣言して使用すればいいのではないでしょうか?

投稿2021/05/17 16:50

編集2021/05/17 16:52
rinjinto

総合スコア170

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

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

rinjinto

2021/05/17 16:56

追加したコード部分を関数にした方がコードの修正漏れなどが減るので、できれば関数化したいところです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問