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

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

ただいまの
回答率

90.34%

  • C

    3986questions

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

一方向リストプログラムの問題がわかりません

解決済

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 651

ababab

score 51

指定されたキーを削除するというコードです。

scanf("%d",&data); //指定するキーをdataに入れる
a = &listhead; //listheadのアドレスをaに入れる
while(a -> next != NULL){ //listheadの中の変数nextがNULLでない間
   if( a -> next -> key == data) //listheadの変数nextに入っているkeyがdataと同じだったら
      break;
   a = a -> next; //aをaの変数nextのアドレスに変える
}

if( a -> next == NULL) //aの変数nextがNULLだったら
   prtinf("キーがありません");
else {
    ptr = a -> next; //①
   a -> next = ptr -> next (またはa -> next -> next);②
   free( ptr ); //ptrを削除(解放)
}


このように解釈しているのですが、特に①と②で何をしているのかがわかりません。
ptrが宣言されていないので、ptrが何なのか、aとの違いはなんなのか....

ご教授いただけたらと思います。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

+1

変数の宣言文が全くありませんから、サンプルプログラムではないですよね。
課題か演習問題でしょうか。構造体のポインタの使い方に関する問題ですね。
だとすると、解答を書いてしまうより考え方をサポートするほうがよいと思いますので
以下を参考に自分で考えてみてください。

1行ずつ見ていって解ること・解らないことを並べてみましょう。
1行目
%d で読み込んでいるので、data は int型であることが解ります。
2行目
a は listhead と同じ型のポインタ
listhead の型は解らない
3行目
a->next とあるので、a は構造体のポインタ → listhead は構造体
4行目  ☆ここがポイント
data と比較しているので、a->next->key は data と同じ int型
では a->next はなんでしょう?

と、順に追ってみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

一方向連結リストを自体をよくわかってないのではないでしょうか。

一方向連結リストはノード(構造体として定義)の集まりです。
ノードの保持する情報は、
  • 記憶したい値
  • 次のノードのアドレス
です。
「俺は3という数を覚えておくように言われた、次の数は2000番地にいる奴が知っているぞ」
みたいな感じです。

a:削除対象の手前のノード
foo->next:ノードfooの次のノード(のアドレス)
ptr:削除対象のノード
と脳内変換すれば意味がわかると思います。
(というわけでこのコード、変数の名前があまりよろしくないです。)

A--->B--->C--->Dという風に連結されたリストがあって、Cを消したいとなれば
Cの手前であるBの接続先を
Cの次であるDに変えますよね?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

指定されたキーのデータを削除するために、その前後のデータのリンクをつなげなおしています。

a,b,c,d,eとデータが並んでいます。
aはbへのリンクを持っています。
bはcへのリンクを持っています。
cも
dも

次のデータへの参照(リンク)を持つことによって次のデータにアクセスできるのがリストなのですが、例えばbがただ削除されてしまっては参照が途切れてしまうので、bが削除される場合はaが保持する次の参照をcに変更してやります。

それを行っているのが①、②です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/24 10:22

    回答ありがとうございます。
    データのリンクをつなげなおすというのがよくわかりませんでした..すみません。
    ptr = a -> nextは、ptrの中にaの中にある変数nextの値を入れるということでよろしいでしょうか?

    キャンセル

  • 2015/07/24 10:54

    そうなります。
    ptrはポインタなのでアドレスが代入されます。

    キャンセル

0

結論から言うと
ptrはリスト中でaの次の要素です。
(同じリストの別要素なので、各要素が示す値が異なるだけで構成は同じ)

実際に値を当てはめてみればわかりやすいと思います。

たとえば1->2->3となっているリストで
keyが2の場合、
whileはa->next->key == 2
つまりa->key==1で抜けます。

このとき
a->key == 1
a->next->key == ptr->key == 2
a->next->next->key == ptr->next->key == 3
です。

ここで、a->next = ptr->nextにする(aの次をaの次の次にする)ので、
1->2->3で1から2を指しているポインタを3を指すようにします。
これで1->3となってリストから2が消えます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

すでに回答は出ているので分かりやすく言いますと、この問題(後半)は、
並んでいる列から誰か抜けて、前に詰め直す作業をしています。

そして、その列というのは一方向(単方向)リストで、
ポインタで前につながっているわけですから、
ポインタを前につなぎ直すことが削除と等しくなるわけです。

番号札を持っていないとダメなタイプの窓口で、
番号札を前の者に渡してしまうと、
たとえそこに並んでいても順番が飛ばされるようなイメージです。

理解できればいくらでも問題は解けるようになるので、
何をしているのかのイメージを描くようにしましょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ptrは、listheadのポインタ変数。
a や a->next も同じくlistheadのポインタ変数ですね。

削除するキーが見つかったのが、a->nextなんで、
ptrにa->nextを保持させておいて、a->nextにa->next->nextを代入(繋げる)。
で、いらなくなったptr(保持しておいたa->next)のメモリを解放。


投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    3986questions

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