🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

3回答

737閲覧

リストの削除についてお願いいたします。

txty

総合スコア303

C

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

0グッド

0クリップ

投稿2021/03/15 06:24

編集2021/03/22 06:24

リストのプログラムです。
初心者が書いており危険かもしれないので
引用、参考で起こったあらゆる責任は一切負いません。

前回の質問で削除の方法を教えてもらったのですが、削除の方法がうまく実装できません。
削除したいノードのひとつ前のノード->next = 削除したいノード->next

しなきゃいかんので、まずは 「削除したいノードのひとつ前のノード」
つまり X->next == 削除したいノード である X を見つけることになりますとのことですが

以下のコードについて、どこに、どう書いたらいいでしょうか。よろしくお願いします。
試しに3番目を消そうとしてtop3->next=top4;を消して,top2->next=top3->next; とかいてみたんですが
うまくいかなかったのでお願いします。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4struct SUUJI{ 5 int suuji; 6 struct SUUJI *next; 7}; 8 9int main(void){ 10 11 12struct SUUJI *top5; 13struct SUUJI *top4; 14struct SUUJI *top3; 15struct SUUJI *top2; 16struct SUUJI *top1; 17 18top5=(struct SUUJI *)malloc(sizeof(struct SUUJI)); 19 20top5->suuji=5; 21 22top5->next=NULL; 23 24top4=(struct SUUJI *)malloc(sizeof(struct SUUJI)); 25 26top4->suuji=4; 27 28top4->next=top5; 29 30top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); 31 32top3->suuji=3; 33 34top3->next=top4; 35 36top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); 37 38top2->suuji=2; 39 40top2->next=top3; 41 42top1=(struct SUUJI*)malloc(sizeof(struct SUUJI)); 43 44top1->suuji=1; 45 46top1->next=top2; 47 48 49while(top1!=NULL){ 50 51printf("%d->", top1->suuji); 52 53top1=top1->next; 54 55} 56 57printf("\n"); 58//追記 やっぱりやめた 59return 0; 60} 61

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

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

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

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

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

guest

回答3

0

ベストアンサー

C

1#include <stdio.h> // printf 2#include <stdlib.h> // malloc 3 4struct SUUJI { 5 int suuji; 6 struct SUUJI *next; 7}; 8 9int main(void) 10{ 11 struct SUUJI *top5; 12 struct SUUJI *top4; 13 struct SUUJI *top3; 14 struct SUUJI *top2; 15 struct SUUJI *top1; 16 17 top5 = (struct SUUJI *)malloc(sizeof(struct SUUJI)); 18 top5->suuji = 5; 19 top5->next = NULL; 20 21 top4 = (struct SUUJI *)malloc(sizeof(struct SUUJI)); 22 top4->suuji = 4; 23 top4->next = top5; 24 25 top3 = (struct SUUJI *)malloc(sizeof(struct SUUJI)); 26 top3->suuji = 3; 27 top3->next = top4; 28 29 top2 = (struct SUUJI *)malloc(sizeof(struct SUUJI)); 30 top2->suuji = 2; 31 top2->next = top3; 32 33 top1 = (struct SUUJI *)malloc(sizeof(struct SUUJI)); 34 top1->suuji = 1; 35 top1->next = top2; 36 37 for (struct SUUJI *p = top1; p != NULL; p = p->next) 38 printf("%d->", p->suuji); 39 printf("\n"); 40 41 top2->next = top3->next; 42 43 for (struct SUUJI *p = top1; p != NULL; p = p->next) 44 printf("%d->", p->suuji); 45 printf("\n"); 46}

実行結果

text

11->2->3->4->5-> 21->2->4->5->

リストから3番目の要素が削除されています。

追記
本当に理解していますか?
top2->next = top3->next; の代わりに
top2->next = top2->next->next; でもいいし、
top2->next = top4; でもいいのが分かりますか?

追記2

C

1#include <stdio.h> // printf 2#include <stdlib.h> // malloc, free 3 4struct SUUJI { 5 int suuji; 6 struct SUUJI *next; 7}; 8 9void list_print(const struct SUUJI *p) 10{ 11 if (p == NULL) return; 12 printf("%d", p->suuji); 13 while (p = p->next) printf("->%d", p->suuji); 14 printf("\n"); 15} 16 17void list_add(struct SUUJI **lp, int val) 18{ 19 struct SUUJI *np = malloc(sizeof *np); 20 np->suuji = val; 21 np->next = *lp; 22 *lp = np; 23} 24 25struct SUUJI *list_delete(struct SUUJI **lp, int val) 26{ 27 for (struct SUUJI *p; p = *lp; lp = &p->next) 28 if (p->suuji == val) { 29 *lp = p->next; 30 return p; 31 } 32 return NULL; 33} 34 35void list_free(struct SUUJI *p) 36{ 37 while (p) { 38 struct SUUJI *q = p; 39 p = p->next; 40 free(q); 41 } 42} 43 44int main(void) 45{ 46 struct SUUJI *list1 = NULL; 47 48 list_add(&list1, 50); 49 list_add(&list1, 40); 50 list_add(&list1, 30); 51 list_add(&list1, 20); 52 list_add(&list1, 10); 53 list_print(list1); 54 55 struct SUUJI *p = list_delete(&list1, 30); 56 free(p); 57 list_print(list1); 58 59 p = list_delete(&list1, 10); 60 free(p); 61 list_print(list1); 62 63 list_free(list1); 64 list1 = NULL; 65}

投稿2021/03/16 02:35

編集2021/03/22 19:24
kazuma-s

総合スコア8224

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

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

txty

2021/03/16 04:03 編集

コメントありがとうございます。すごくわかりやすいコードです。後、自分の書いたコードのどこがおかしいかも指摘してもらえますでしょうか。top2のnextからtop3、top3のnextからtop4のnextを削除。top2のnextからtop4をつないだつもりなのですが何がおかしいのでしょうか。
fana

2021/03/16 03:00

質問文にある > X を見つける とかいう話は全く解決していないように見えるが,良いのだろうか?
txty

2021/03/16 03:09

検索なのかわからないのですが、 まだ手をつけなかったので、この間の回答者さんに教えてもらった方法でたぶんXはひとつ前のアドレスだったような気がするけど今は自分でXがわかればよしという風になりました。実際検索がどんなコードになるかしらないので。
txty

2021/03/16 03:28

kazuma-sさん>top2->next = top3->next; top2->next = top4; は気がついてました。
txty

2021/03/16 04:22 編集

kazuma-sさん>コードの方をかえる場合、 top3の両端のリンクを消すために top3->next=top4を削除 top2->next=top3を削除 top2->next=top3->next;を追加 とするは駄目なんでしょうか。 すいません。コード見直したら書いてありました。 ただ上の思考をしてしまうため、なんで駄目で、kazuma-sさんが書いたコードが大丈夫なわけを知りたいですが。 top2->nextに上書きすればいいから削除はいらないということですか?
txty

2021/03/23 06:25 編集

回答の追記、ありがとうございます。自分にはもったいないコードです。質問なのですが、上に書いてもらった、自分のコードにしてしまいましたが、今の状態からfree(top3);して大丈夫でしょうか。単純に削除ノードのメモリを解放するだけ(free)するだけだと、親ノードはまだ削除ノードを指したままの状態であると、どこかのページで読んだため。今はmain(){}の終わりだからって体裁をとっています。
dodox86

2021/03/23 05:19

>@txtyさん 横からですみませんが、要素の削除について質問していたのに、BAが既についた回答でのコメント欄で更に別の質問はマナー違反です。
txty

2021/03/23 06:26 編集

dodox86さん>では、あらめて質問を作ることにします。削除のfree()の質問だけこちらに残します。ご指摘ありがとうございます。修正しました。
guest

0

ひとつ前のノード->next → 削除したいノード->next → 一つあとのノード->next

これを、

ひとつ前のノード->next → 一つあとのノード->next

と、すればいいのです
さあ、どうすればいいのか考えましょう

投稿2021/03/15 06:46

y_waiwai

総合スコア88038

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

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

txty

2021/03/15 06:59

時間がかかりすぎるので無理です。どうか教えてもらえませんか。教えてもらえない場合、後で、これ持ち帰ってじっくり考えることになります。
txty

2021/03/15 07:20

top4->next=top5; //top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); //top3->suuji=3; top2->next=top4->next; //top3->next=top4; top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top2->suuji=2; top2->next=top3; すいません。実行エラーがでてできません。どこがおかしいのでしょうか。
dodox86

2021/03/15 07:30

思った結果が出るまでコードをこねくり回すのではなく、図で(絵で)書いてtopとかメンバー変数nextとかの値を頭の中で確認しましょう。。。
txty

2021/03/15 07:35

そうするかもしれません。失礼ですが上に提示したコードは正しいでしょうか。せめてそこまでは教えてもらえるとありがたいのですが。後ろからメモリ確保して、前から順番にたどっていくコードにしたつもりなのですが。
dodox86

2021/03/15 07:42

> 失礼ですが上に提示したコードは正しいでしょうか。せめてそこまでは教えてもらえるとありがたいのですが。 > top2->next=top4->next; > //top3->next=top4; > > top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); 少なくともtop2が新しい領域のポインタで上書きされているので、明らかに間違いです。この前段のコードが分かりませんが、top2は有効なままですね。nextを使っているし。("この前段のコードが分かりません"と書きましたが、それを貼り付けてまた聞かないでくださいね)
txty

2021/03/15 07:45

あっそっちじゃなくて質問に書いてあるコードについてききたかったです。自分で書くのはじめてだったので。よろしくお願いいたします。
dodox86

2021/03/15 07:53 編集

> そっちじゃなくて質問に書いてあるコードについてききたかったです。 えっと、すみませんが何を問われているのか分かりません。質問文中に示されたコードは単方向リストのプログラムで、それに対して「要素を削除する」コードを追加したいのですよね。そのコードはまだ無い訳です。で、それに対して既に回答をいただいているのですよね。合っているかどうか、判定以前の問題ではないでしょうか。あえて???な点を指摘するなら、 > while(top1!=NULL){ > > printf("%d->", top1->suuji); > > top1=top1->next; > > } となっていますが、言うなればtop1は一番先頭の要素だったはずですが、top1をnextで上書きして行ったら、二度と先頭が分からなくなってしまうのではないですか。これは致命的では。使い捨てなら別にそれでも良いですけど。(良く考えてみてください)
dodox86

2021/03/15 07:58

尚、ご提示のコードをコンパイルして動かして確認した訳ではありません。一見しての感想(気づいたところ)のみ、です。
txty

2021/03/15 08:28 編集

実行結果 1->2->3->4->5-> 何がいけないのかわからないのですがわたしはどうすべきでしたか。
dodox86

2021/03/15 11:45

> 何がいけないのかわからないのですがわたしはどうすべきでしたか。 ご提示のプログラムではtop1からtop5までmallocで動的にメモリを割り当てていますよね。while()ループではtop1からnextの構造体メンバーを取り出して、top5のnextの値、NULL(末端)まで辿っていますよね。nextの値を常にtop1に上書きしちゃっているのですから、whileループを抜けたときには、top1の元の値は分からなくなってしまっています。先頭要素top1が分からなくなってしまいますが、それで良いのですか。最終的なプログラムは完成するのですか、ということを指摘しています。txtyさんがそれで良いというのであれば、別にそれで良いです。(なぜならば、txtyさんのプログラムなのですから)
txty

2021/03/16 01:17 編集

調べたいですが..やり方が思い浮かびません。完成けいは出せないです。 解決方を知っていらしたら教えてください。
txty

2021/03/16 02:07 編集

絵を書いてその通り書いたのに、エラーでした。どうすればできますか top4=(struct SUUJI *)malloc(sizeof(struct SUUJI)); top4->suuji=4; top4->next=top5; top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top3->suuji=3; //top3->next=top4; top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top2->suuji=2; top2->next = top3->next; //top2->next=top3; top1=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top1->suuji=1; top1->next=top2; 実行結果が1->2->でとまります(間違い)
dodox86

2021/03/16 02:50

> 実行結果が1->2->でとまります(間違い) これは恐らく > top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); > top3->suuji=3; > //top3->next=top4; としちゃっているので、top3->nextの値が"たまたま"NULLになっていて、その後に > top2->next = top3->next; > //top2->next=top3; としているからでしょう。「絵を書いてその通り書いたけどダメだった」のは、 1. その絵自体が正しい設計を反映していなかった。 2. その絵自体が正しくない設計を反映していた。 3. 絵は正しかったけど、コードでの実装がそれを反映していなかった。 のいずれかだったと思います。たぶん。
fana

2021/03/16 02:54

そのコードが何なのかが謎すぎる. 「リストから要素を削除」って言ったら,「【既に構築済みのリスト】から特定の要素を取り除く」操作のことを指すと思うんだけど…?
txty

2021/03/16 03:00

dodoxさんの言う通りな気がしてきました。 fanaさん>私の認識で、質問でリストを構築していて、リンクを書き換えて、top3を通らなくして、削除と呼んでいたんですが駄目?。
dodox86

2021/03/16 03:00

>@fanaさん 私もそう考えるのですが、各要素について、mallocで取得した領域のfreeなど言及されていることもないので、質問者であるtxtyさんが求めている答えとは異なるのかもしれません。私は、これ以上の指摘は止めることにします。
fana

2021/03/16 03:08 編集

構築済みのリスト と 削除したい要素を指定するための何らかの情報 とが入力されたときに, 後者の情報に基づいて,リスト内から 質問文で言うところのXを探し出して,そこのリンクを適切に繋ぎ変える というのが私の想像する「リストから要素を削除」という操作. どうやらこれとは全く異なる何かを実装されている様子なので「謎」と述べたまで. (要は,やりたいことが何なのかがわからぬ)
txty

2021/03/16 03:22 編集

top3の削除がやりたいです。関数もなにも使っていませんがリンクはつなぎかえたつもりでした。。使い道もわかりません。ただリンクを知りたかったという。好きな場所を消すが正しいとして、まだ、全然そこまでいたってないです
guest

0

top3->next=top4;を消して,top2->next=top3->next;

↑先に消してはダメ。↓みたいな感じに繋ぎ変えてから中間を消さないと。

top2->next=top3->next; free(top3);

投稿2021/03/15 06:32

HogeAnimalLover

総合スコア4830

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

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

txty

2021/03/15 06:48 編集

top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top3->suuji=3; //top3->next=top4; top2->next=top3->next; free(top3); top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); と入力したのですが実行のエラーがでてしまいました。 やっと上のプログラムが書けるようになったばっかしなので、どこにどう書けばいいかおしえてもらえるでしょうか。
HogeAnimalLover

2021/03/15 07:16

順番がおかしいので一部だけ見てもわかりません。
txty

2021/03/15 07:23

順番は後ろからメモリ確保してwhileループで先頭からみていくと思ったのですが間違いでしょうか。
txty

2021/03/16 01:19 編集

削除の絵を書いてみたのですがtop3の削除は top4=(struct SUUJI *)malloc(sizeof(struct SUUJI)); top4->suuji=4; top4->next=top5; top3=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top3->suuji=3; //top3->next=top4; top2=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top2->suuji=2; top2->next = top3->next; //top2->next=top3; top1=(struct SUUJI*)malloc(sizeof(struct SUUJI)); top1->suuji=1; top1->next=top2;
txty

2021/03/16 01:21 編集

上記のとおりやりましたが 実行結果が1->2->で止まってしまいます。なぜでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問