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

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

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

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

Q&A

解決済

2回答

2389閲覧

双方向循環リストにおける選択ソート

submaru

総合スコア18

C

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

0グッド

0クリップ

投稿2020/08/02 13:14

編集2020/08/02 14:10

前提・実現したいこと

双方向循環リストでの選択ソートを削除と挿入をもって実装したい。

発生している問題・エラーメッセージ

交換にあたるコードがわからない。
また、書いてみたが無限ループや完璧でないソートになった。

該当のソースコード

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <time.h> 4 5typedef struct node{ 6 struct node *prev; 7 struct node *next; 8 int value; 9}NODE; 10 11#define DUMMY -1 12#define MAX 99 13#define NUM 10 14 15NODE* make_list(int num); 16NODE* make_cell(int val); 17void insert_cell_to_list(NODE *x, NODE *p); 18NODE* delete_cell_from_list(NODE *x); 19void print_list(NODE *link_list_head); 20void free_list(NODE *link_list_head); 21void selection_sort_cell(NODE *link_list_head); 22 23int main(void){ 24 NODE *list_head; 25 26 srand((unsigned int)time(NULL)); 27 28 list_head=make_list(NUM); 29 printf("ランダムで作成したリストを表示\n"); 30 print_list(list_head); 31 selection_sort_cell(list_head); 32 printf("選択ソート後\n"); 33 print_list(list_head); 34 printf("\n"); 35 36 free_list(list_head); 37 38 return 0; 39} 40 41NODE* make_list(int num){ 42 NODE *list, *cel, *list_head; 43 int i; 44 45 list=make_cell(DUMMY); 46 list->next=list; 47 list->prev=list; 48 list_head=list; 49 50 for(i=0; i<num; i++){ 51 cel=make_cell(rand()%MAX); 52 list=list->next; 53 insert_cell_to_list(cel, list); 54 } 55 return (list_head); 56} 57 58NODE* make_cell(int val){ 59 NODE *p; 60 61 p=(NODE*)malloc(sizeof(NODE)); 62 if (p == NULL) { 63 fprintf(stderr, "Memory allocation error!\n"); 64 exit(-1); 65 } 66 p->value =val; 67 p->next =NULL; 68 p->prev =NULL; 69 return(p); 70} 71 72void insert_cell_to_list(NODE *x, NODE *p){ 73 74 x->prev = p; 75 x->next = p->next; 76 p->next->prev = x; 77 p->next = x; 78} 79 80NODE* delete_cell_from_list(NODE *x){ 81 82 x->prev->next = x->next; 83 x->next->prev = x->prev; 84 return (x); 85} 86 87void print_list(NODE *link_list_head){ 88 NODE *p; 89 90 for (p = link_list_head->next; p != link_list_head; p = p->next) { 91 printf("%d\n", p->value); 92 } 93} 94 95void free_list(NODE *link_list_head){ 96 NODE *p, *q; 97 98 p=link_list_head; 99 p->prev->next = NULL; 100 while (p!=NULL){ 101 q=p->next; 102 free(p); 103 p=q; 104 } 105} 106 107void selection_sort_cell(NODE *link_list_head){ 108 NODE *p, *q, *low, *tmp; 109 110 for (p = link_list_head->next; p != link_list_head->prev; p = p->next) { 111 low = p; 112 for (q = p->next; q != link_list_head; q = q->next) { 113 if (low->value > q->value) { 114 low = q; 115 } 116 } 117 /* ここからソート(未完成) */ 118 tmp = delete_cell_from_list(low); 119 insert_cell_to_list(tmp, p); 120 tmp = delete_cell_from_list(p); 121 insert_cell_to_list(tmp, low->prev); 122 p = p->next; 123 } 124}

試したこと

ソート部分を自分が考えたように書いたが、うまくいかなかった。

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

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

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

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

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

guest

回答2

0

ベストアンサー

もっと簡単になるかもしれませんが、とりあえずこれで OK なはず。

diff

1void selection_sort_cell(NODE *link_list_head){ 2 NODE *p, *q, *low, *tmp; 3 4- for (p = link_list_head->next; p != link_list_head->prev; p = p->next) { 5+ for (p = link_list_head->next; p != link_list_head->prev; ) { 6 low = p; 7===== 8 /* ここからソート(未完成) */ 9- tmp = delete_cell_from_list(low); 10- insert_cell_to_list(tmp, p); 11- tmp = delete_cell_from_list(p); 12- insert_cell_to_list(tmp, low->prev); 13- p = p->next; 14+ if (p == low) 15+ p = p->next; 16+ else { 17+ NODE *prev = low->prev; 18+ tmp = delete_cell_from_list(low); 19+ insert_cell_to_list(tmp, p); 20+ tmp = delete_cell_from_list(p); 21+ if (p == prev) 22+ insert_cell_to_list(tmp, low); 23+ else 24+ insert_cell_to_list(tmp, prev); 25+ p = low->next; 26+ } 27 } 28}

追記
for文はそのままで、「ここからソート(未完成)」の部分だけの変更でできます。

diff

1 /* ここからソート(未完成) */ 2- tmp = delete_cell_from_list(low); 3- insert_cell_to_list(tmp, p); 4- tmp = delete_cell_from_list(p); 5- insert_cell_to_list(tmp, low->prev); 6- p = p->next; 7+ if (p != low) { 8+ NODE *prev = low->prev; 9+ tmp = delete_cell_from_list(low); 10+ insert_cell_to_list(tmp, p); 11+ tmp = delete_cell_from_list(p); 12+ if (p == prev) 13+ insert_cell_to_list(tmp, low); 14+ else 15+ insert_cell_to_list(tmp, prev); 16+ p = low; 17+ }

追記2
もう少し簡単になりました。

C

1 /* ここからソート(未完成) */ 2 if (p != low) { 3 tmp = low->prev; 4 if (tmp == p) tmp = low; 5 delete_cell_from_list(low); 6 insert_cell_to_list(low, p); 7 delete_cell_from_list(p); 8 insert_cell_to_list(p, tmp); 9 p = low; 10 }

追記4
さらに簡単にできます。
if (p != low) {} は無くても大丈夫です。

投稿2020/08/02 17:25

編集2020/08/03 01:23
kazuma-s

総合スコア8224

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

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

submaru

2020/08/02 17:43

追記の方のコードを参考にさせてもらい変更したところ、正常に動くようになりました!わざわざ書いてくださってありがとうございました!
guest

0

...a←→b←→c...A←→B←→C...とリストがあった時
bとBを交換する場合
(真面目にやる場合)

  • bのprev/nextとBのprev/next をそれぞれ交換し
  • a.nextとc.prevをBにして
  • A.nextとC.prevをbにする。

(不真面目にやる場合)
b.valueとB.valueを交換する。

投稿2020/08/02 14:36

asm

総合スコア15149

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

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

submaru

2020/08/02 15:04

質問文の通り削除(取り出し)と挿入で行いたいのですが、その場合はどのようにするかはわかりますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問