• 締切済み

線形リストのコードでどーしても理解できない個所があります。

線形リストのコードでどーしても理解できない個所があります。 (以下、コード部分) typedef struct __node { char name[20]; char tel[16]; struct __node *next; } Node; typedef struct { Node *head; Node *tail; } List; Node *AllocNode(void) { return ((Node *)calloc(1, sizeof(Node))); } /*--- 新たに生成したノードを先頭へ挿入 ---*/ void InsertNode(List *list, const char *name, const char *tel) { Node *ptr = list->head; list->head = AllocNode(); strcpy(list->head->name, name); strcpy(list->haed->tel, tel); list->head->next = ptr; } /*--- pが指すノードの直前にノードを挿入 ---*/ void PutNodeP(List *list, Node *p, const char *name, const char *tel) { if (p == list->head) InsertNode(list, name, tel); else { Node *temp = AllocNode(); if (p == list->tail) list->tail = temp; else *temp = *p; strcpy(p->name, name); strcpy(p->tel, tel); temp->next = p; } } 上の29行目以降の≪pが指すノードの直前にノードを挿入≫についてです。 if文部分については理解できますが、else文部分について、何をやっているのかわからないです。Cの基本的な部分(ポインタも含めて)については充分に理解しているつもりです。 どなたか御教授頂けないでしょうか。 長々と書いてしまいましたがよろしくお願いします。

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

list->tail が指しているのはダミーのノードで実はデータが入っていないと見た>#3... あれ? でもそうするとダミーのノードが 2つもいるから無駄だ. 最初に空のリストをどのように作っていますか?

回答No.3

なるほど。Tacosanさんの説明でどのように挿入しているかがわかりました。後に挿入して中身を入れ替えているのですね。 ただ、そうなると以下の部分、elseはいらないんじゃないでしょうか? if (p == list->tail) list->tail = temp; else *temp = *p; *temp = *pの部分、p == list->tailであるかどうかに関わらず実行されるべきだと思うのですが。

kerberosMA
質問者

補足

else文以下です。 字下げがうまく表示されないみたいなので こちら側で付け加えました (かえって見づらくなりましたがお許しください)。 else{ (タブ)Node *temp = AllocNode(); (タブ)if(p == list->tail) (タブ)(タブ)list->tail = temp; (タブ)else (タブ)(タブ)*temp = *p; (タブ)strcpy(p->name, name); (タブ)strcpy(p->tel, tel); (タブ)p->next = temp; }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

や, 「pが指すノードの直前にノードを挿入」というコメントが紛らわしいですが, 得られるリストだけを見れば「p が指すノードの直前に挿入した『よう』」には見えます>#1. で本題ですが, 図を描いて動作を調べてみましたか? ・p の指すノードの後に新しいノードを挿入する ・今挿入したノードに p の指すノードの内容をコピーする ・もともと p が指していたノードには新しい内容を入れる という一連の処理をしているだけです.

回答No.1

このコード、本当に正しいのでしょうか? pが指すノードの「直後」ではなく「直前」に挿入するんですよね? そうするとheadからlistを辿っていかないといけないと思うのですが、そうしているようには見えないですね。 詳しいコードは書きませんが、こんな流れになると思います。 if (p == list->head) InsertNode(list, name, tel); else { // p の直前のノードを見つける(仮にp0とします)。 // 新しいノードを生成する(temp)。name、telも設定します。 // tempをp0とpの間に挿入する。  }  直前に挿入するので、pがtailであるかどうかは気にしなくていいはずです。

kerberosMA
質問者

補足

すいません、一部誤りがありました。 44行目について (誤)temp->next = p; (正)p->next = temp; 以上です。 本当に申し訳ありませんでした。 以上です、よろしくお願い致します。

関連するQ&A

専門家に質問してみよう