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

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

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

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

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

Q&A

解決済

4回答

1235閲覧

双方向リストを作ったが、deleteした後にリストの中身を表示させると実行時間超過で中断されてしまう

aoa

総合スコア4

C

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

リストボックス

ユーザーがリストから1つ以上のアイテムを選択できるようにするGUI要素です。

0グッド

0クリップ

投稿2022/11/15 15:32

編集2022/11/16 01:28

概要

2つの頭(ダミー)がある双方向循環リストにおいて
(1)入力順と同じ順番にリストを作成する
(2)1つ目のリストは要素が奇数、2つ目のリストは要素が偶数のものを消去する
(3)1つめのリストの末尾に2つ目のリストを繋げ、2つ目のリストの末尾に1つ目のリストの先頭ダミーにつなぐ。尚、2つ目の先頭のダミーは消去する。

というものをプログラムをしたいのですが、2つ目のリスト内の要素が偶数のものを消去を行なった後にリストを出力するときに時間超過で中断されてしまいます。複雑なことは行っていないはずなのに、何がいけないにでしょうか?

実行例

>1 >2 >3 [1][2][3]{3}{2}{1} [1][2][3]{3}{2}{1} [2]{2} [1][3]{3}{1} [2][1][3]{3}{1}{2}

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

>1 >2 >3 [1][2][3]{3}{2}{1} [1][2][3]{3}{2}{1} この先が行われない

該当のソースコード

C

1#include<stdio.h> 2#include<stdlib.h> 3 4typedef int elementtype; 5 6struct dlnode { 7 elementtype element; 8 struct dlnode *prev, *next; 9}; 10 11typedef struct dlnode* dllist; 12 13void print_dllist(dllist d) {/*d の指しているダミーの節点から、next を順にたどって自分自身に戻るまで element を [と] で挟ん 14で標準出力に出力し続けたのち、prev を順にたどって自分自身に戻るまで element を{と}で挟んで標 15準出力に出力し続ける関数 (最後に改行)。 */ 16 dllist n; 17 n = d->next; 18 while(n != d) { 19 printf("[%d]", n->element); 20 n = n->next; 21 } 22 n = n->prev; 23 while(n != d) { 24 printf("{%d}", n->element); 25 n = n->prev; 26 } 27 printf("\n"); 28 29} 30 31void insert(dllist p, elementtype e) { /*p の指している節点の prev に、element として e を含む節点を挿入する関数。 */ 32 dllist n; 33 n = (struct dlnode *) malloc (sizeof (struct dlnode)); 34 n->element = e; 35 36 if(p->next == NULL && p->prev == NULL) { 37 p->prev = n; 38 n->next = p; 39 n->prev = p; 40 p->next = n; 41 } else { 42 n->next = p; 43 n->prev = p->prev; 44 p->prev->next = n; 45 p->prev = n; 46 } 47} 48 49void delete(dllist p) { /*p の指している節点のみを削除する関数 (p の前後のポインタを繋ぎ変えて、free 関数により削除した 50節点のメモリを解放する)。*/ 51struct dlnode *next, *prev; 52 prev = p->prev; 53 next= p->next; 54 if (prev != NULL) 55 prev->next = next; 56 if (next != NULL) 57 next ->prev = prev; 58 free(p); 59} 60void append_dllist(dllist d1, dllist d2) {/*d1、d2 の指している節点をダミーの節点とする 2 つの双方向リストを連結する関数 (d1 から next をた 61どっていくと、1 つめの双方向リストの要素に続いて 2 つめの双方向リストの要素が現れ、d1 に戻っ 62てくるように定義し、2 つめのダミーの節点 d2 のメモリは free 関数によって解放する)*/ 63 dllist n; 64 n = d1; 65 while(n->next != d1) { 66 n = n->next; 67 } 68 n->next = d2; 69 70 while(n->next != d2) { 71 n = n->next; 72 } 73 n->next = d1; 74 free(d2); 75} 76 77int main(void) { 78 int i; 79 char buf[128]; 80 dllist d1, d2, p; 81 82 d1 = (struct dlnode *)malloc(sizeof(struct dlnode)); 83 d1->prev = NULL; 84 d1->next = NULL; 85 86 d2 = (struct dlnode *)malloc(sizeof(struct dlnode)); 87 d2->prev = NULL; 88 d2->next = NULL; 89 90 91 while(fgets(buf,sizeof(buf),stdin) != NULL) { 92 sscanf(buf,"%d", &i); 93 insert(d1, i); 94 insert(d2, i); 95 } 96 print_dllist(d1); 97 print_dllist(d2); 98 99 p = d1; 100 do { 101 if(p->element % 2) { 102 p = p->next; 103 delete(p->prev); 104 105 } 106 p = p->next; 107 }while(p!=d1||p->next!=d1); 108 109 p = d2; 110 do{ 111 if(!(p->element % 2)){ 112 p = p->next; 113 delete(p->prev); 114 115 } 116 p = p->next; 117 }while(p!=d2||p->next!=d2); 118 119 print_dllist(d1); 120 print_dllist(d2); 121 122 append_dllist(d1, d2); 123 print_dllist(d1); 124 return 0; 125}

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

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

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

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

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

jimbe

2022/11/15 15:50 編集

時間超過ということはどこかで無限ループしているのでしょう。 コードの一行毎に printf で何かマークを出すようにし、どこでループしているかを調べては如何でしょうか。 また、コードをコピペしてもコンパイルエラーになっています。 teratail への貼り付けはソースファイルの中身そのままにするようにしてください。
aoa

2022/11/15 15:59

申し訳ありません。 訂正前のものを添付していました。
kazuma-s

2022/11/15 17:57

「頭(ダミー)がある双方向循環リスト」の頭の prev と next は NULL ではなく、 最初は 頭のアドレスを入れます。
dodox86

2022/11/16 02:51

タグの「リストボックス」は、GUIの要素の種類のひとつであって、今回は関係無いと思います。
guest

回答4

0

https://pythontutor.com/c.html を利用し、コードの流れを可視化する。

投稿2022/11/15 16:13

atcoderyellow

総合スコア481

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

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

0

ベストアンサー

質問のコードは全角スペースが入っていたり、do文の最後にセミコロンがないなど
コンパイル不可能なものです。
また、append_dllist も間違っています。

リストのヘッドの初期化を insert の中で行っているようですが、
ヘッドを作った時に初期化するほうが良いと思います。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4typedef int elementtype; 5 6struct dlnode { 7 elementtype element; 8 struct dlnode *prev, *next; 9}; 10 11typedef struct dlnode *dllist; 12 13void print_dllist(dllist d) 14{ 15 for (dllist n = d->next; n != d; n = n->next) 16 printf("[%d]", n->element); 17 for (dllist n = d->prev; n != d; n = n->prev) 18 printf("{%d}", n->element); 19 printf("\n"); 20} 21 22void insert(dllist p, elementtype e) 23{ 24 dllist n = malloc(sizeof(struct dlnode)); 25 n->element = e; 26 n->next = p; 27 n->prev = p->prev; 28 p->prev->next = n; 29 p->prev = n; 30} 31 32void delete(dllist p) 33{ 34 p->prev->next = p->next; 35 p->next->prev = p->prev; 36 free(p); 37} 38 39void append_dllist(dllist d1, dllist d2) 40{ 41 d1->prev->next = d2->next; 42 d2->next->prev = d1->prev; 43 d1->prev = d2->prev; 44 d2->prev->next = d1; 45 free(d2); 46} 47 48int main(void) 49{ 50 dllist d1, d2, p, q; 51 d1 = malloc(sizeof(struct dlnode)); 52 d1->prev = d1->next = d1; 53 d2 = malloc(sizeof(struct dlnode)); 54 d2->prev = d2->next = d2; 55 56 char buf[128]; 57 while (fgets(buf, sizeof buf, stdin)) { 58 int i; 59 sscanf(buf, "%d", &i); 60 insert(d1, i); 61 insert(d2, i); 62 } 63 print_dllist(d1); 64 print_dllist(d2); 65 66 for (p = d1->next; p != d1; p = q) { 67 q = p->next; 68 if (p->element % 2 == 1) delete(p); 69 } 70 for (p = d2->next; p != d2; p = q) { 71 q = p->next; 72 if (p->element % 2 == 0) delete(p); 73 } 74 print_dllist(d1); 75 print_dllist(d2); 76 77 append_dllist(d1, d2); 78 print_dllist(d1); 79 return 0; 80}

append_dllist の中で free(d2); の代わりに d2->prev = d2->next = d2; としておいて
main で d2 のリストの free を行ったほうがいいとは思うのですが。

このコードが理解できたかどうかコメントをお願いします。

投稿2022/11/16 01:32

編集2022/11/16 01:51
kazuma-s

総合スコア8224

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

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

aoa

2022/11/16 05:13

初期化の部分が参考になります。 訂正前のコードを添付してすみませんでした。 ありがとうございました。
guest

0

コードをよく読んだ訳では無いので処理は確認していませんが、 do while() のセミコロンを付け忘れているのでは無いでしょうか

投稿2022/11/16 00:44

編集2022/11/16 00:46
eipi-1-0

総合スコア8

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

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

0

まずはデバッグできる環境を整えてはどうでしょうか。
Windowsなら、VisualStudioやEclipseなどがあります

ブレークポイントを設定して実行を止め、変数の中身を見ることができます。
また、1行づつ実行して、どう動作するかを見れます。

これで、どこがおかしいのかわからない、ってことはなくなりますよ

投稿2022/11/16 00:13

編集2022/11/16 00:20
y_waiwai

総合スコア87774

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問