• 締切済み

リスト構造の挿入と削除について

ある本にリストについてのっていたのですが、その本に ソースがのっていたのですが、わかりません。 ソースは、下記に載せたのがすべてです。 リストについてですが、char line[256];は、データの部分で すか?p->prev->next = p->next;これは、かなり複雑ですね こんな参照の方法ありましたっけ? p->next->prev = p->prev;これも同じです。 p->next = c c->prev = p c->prev->next = p; 上記の3つですが、pとcを代入していますよね、pとcというのは 要素のどの部分でもないですよね。 prevやnextだったら、要素の部分なのでそれをつなぎ換えたり して、リストを組むというのは想像がつくのですが、pとcっていう のは、ただ漠然としていますよね。どこを指しているかわかりま せんよね。char ptr[20];と同じようにptrには、先頭のアドレスが 入っていたように、pとcには、何か具体的な情報が入っている のでしょうか? /* 両隣へポインターをつなぐ */ p->prev = c->prev; p->next = c; /* 両隣のポインターをつなぎ換える */ c->prev->next = p; c->prev = p; 上記も複雑ですね・・・ 解説お願いします・・・ free(p);はメモリの解放ですか? リスト *prevは前の要素へのポインター *nextは後ろの要素へのポインター typedef struct list_t { char line[256]; struct list_t *prev; struct list_t *next; } LIST; delete_line(LIST *p) { p->prev->next = p->next; p->next->prev = p->prev; free(p); } insertt_line(LIST *c, LIST *p) { /* 両隣へポインターをつなぐ */ p->prev = c->prev; p->next = c; /* 両隣のポインターをつなぎ換える */ c->prev->next = p; c->prev = p; } ご指導よろしくお願いします。

みんなの回答

  • TT414
  • ベストアンサー率18% (72/384)
回答No.4

同じような質問があり、回答がたくさん出てます、参考にどうぞ。 http://www2.realint.com/cgi-bin/tarticles.cgi?pointc+22566

参考URL:
http://www2.realint.com/cgi-bin/tarticles.cgi?pointc+22566
noname#30727
noname#30727
回答No.3

>pとcっていうのは、ただ漠然としていますよね。どこを指しているかわかりませんよね。 >char ptr[20];と同じようにptrには、先頭のアドレスが入っていたように、pとcには、何か具体的な情報が入っているのでしょうか? 漠然としていていいのです。 例えばprintfにしても、何を表示するかが決まっているわけではありませんよね? 具体的な情報は、呼び出す側が引数で指定するのです。 insertt_lineの場合、100行目と101行目の間に1行挿入させたければ、cには101行目のデータのアドレスを、pには挿入するデータのアドレスを渡すという決まりが存在する事になります。

  • yyamagu
  • ベストアンサー率40% (21/52)
回答No.2

> マルチポストですか? 日下部陽一さんって、あのヘミ猫のvoidさんなんですかね? だとしたら初心者向けに易しく解説するなんてことはきっとないでしょう。参考書を変えてみたらどうですか。 そうじゃなくても、何冊か読んで色々と試しているうちになんとなくわかってくるものだと思います。

  • dial8675
  • ベストアンサー率26% (42/159)
回答No.1

>リストについてですが、char line[256];は、データの部分ですか? そうです。 わからないときは、図を描いてみましょう。 このリストの要素(構造体)は、次の要素へのポインタと、ひとつ前の要素へのポインタと(今回とくに関係ないデータ)を持っています。 それぞれの要素のイメージは、「 ←|p|→ 」こんな感じ。これの左右に同じような要素が連なります。 リストがつながっているなら、右向き、左向きの矢印が一本づつ、計2本が要素と要素の間にはさまれた感じになります。 >p->prev->next = p->next; これはリストから要素pを消す作業でしょう。「pの1個前の要素から見て、次の要素はpの次の要素」といえばいいのかな? >pとcっていうのは、ただ漠然としていますよね pやcはリストの要素(を示すポインタ)です。 printf("%x",p);や、printf("%x",p->next); などすると、16進数でアドレスが表示されますから、見てみましょう。

関連するQ&A

  • 双方向リストについて

    *prevは前の要素へのポインタ *nextは後ろの要素へのポインタ typedef struct list_t { char line[256]; struct list_t *prev; struct list_t *next; } LIST; 削除処理 *pが削除する要素 delete_line(LIST *p) { p->prev->next = p->next; p->next->prev = p->prev; free(p) } *pが挿入する要素 *cが挿入する場所 insert_line(LIST *c, LISt *p) { /*両隣へポインターをつなぐ*/ p->prev = c->prev; p->next = c; /*両隣のポインターをつなぎ換える*/ c->prev->next = p; c->prev = p; } これは、ある本に書かれていたものなのですが、どうしても、理解ができません。図を描きながら追ってみたのですが、cは、挿入する場所を表しているのですが、図で描こうにもどこがその場なのかが、わかりません。あと挿入処理のところでpやcが代入されていますが、pやcは、どこを表しているのですか?この本の説明がおかしいのでしょうか?それとも私の考え方が違うのでしょうか・・・。ご指導いただければありがたいです。

  • 構造体のリスト削除

    かれこれ1時間くらい悩んでいて 問題として 関数delete()を作成し、プログラムを完成させよ(~yabuki/p7.c)。 関数delete()は、与えられたデータをリストから削除するものである。 ただし、データが先頭であっても動作しなければならない。 次のように出力されるはずである。 NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> END PREV hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT sunyon[23] -> END PREV sunyon[23] -> END list ha nakunarimasita /*******/の間に5行のプログラムを入れる。それ以外にmain()関数を 変更してはならない。 .........;の部分に構造体のメンバーを定義せよ。 というもので、Deleteしていくプログラムをつくりたいのですが NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END セグメントエラー となり、続きができていません。 delete関数のif(p->next != NULL){ のところだけやると 最後まで出るみたいですが、うまくいってません よろしくおねがいします。 ↓ソースです・・・ #include <stdio.h> #include <string.h> struct kara { char name[16]; int age; struct kara *next; struct kara *prev; }; struct kara * delete(struct kara *,struct kara *); struct kara * findend(struct kara *); void* printforw(struct kara *); void* printback(struct kara *); int main() { struct kara a, x, f, m, c, *start, *end, *p; char name[128]; strcpy(a.name, "gyuri"); a.age = 23; strcpy(x.name, "sunyon"); x.age = 23; strcpy(f.name, "nicole"); f.age = 20; strcpy(m.name, "hara"); m.age = 20; strcpy(c.name, "jiyon"); c.age = 17; a.next = &x; x.next = &f; f.next = &m; m.next = &c; c.next = NULL; /********************* 5 lines */ a.prev = NULL; x.prev = &a; f.prev = &x; m.prev = &f; c.prev = &m; /*********************/ start = &a; end = findend(start); printforw(start); printback(end); printf("\n"); p = &c; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); x.next = NULL; p = &a; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); p = start; start = delete(start, p); //de senntou wo kaesu if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } return 0; } struct kara * delete (struct kara *start,struct kara *p) { /*if(p->next->next->next->next) { start = p->next->next->next->next; } */ for(p = start;p != NULL;p = p->next) { start = p->next->next->next; p = start; } /* if(p->next) { start = p->next; } if(p->prev) { start = p->prev; } if(p->next != NULL){ p->next->prev = p->prev; } } */ return p; } struct kara * findend(struct kara *start) { struct kara *pl; for(pl = start;pl != NULL; pl = pl->next){ start = pl; } return start; } void* printforw(struct kara *aa) { struct kara *pl; printf("NEXT "); for ( pl = aa; pl != NULL; pl = pl->next) { printf("%s[%d] -> ", pl->name, pl->age); } printf("END\n"); } void* printback(struct kara *cc) { struct kara *pl; printf("PREV "); //for( ; cc != NULL;cc = cc->prev){ for (pl = cc; pl != NULL; pl = pl->prev) { printf("%s[%d] ->", pl->name,pl->age); } printf("END\n"); }

  • 仮引数の変数をローカル変数に格納する理由について

    プログラムの多くは、仮引数のポインタを一度ローカル変数に格納して使っていますが、なぜでしょうか?データが壊れてしまったりするのでしょうか・・・ typedef struct _LIST{ int value; struct LIST *next; struct LIST *prev; }LIST,*LIST_PTR; void func(LIST_PTR list, char *str){ LIST_PTR wk_list; char *wk_str; wk_list = list; wk = str;

  • List構造

    Listの尻にノードを追加する関数で困っています。 以下に、ソースの一部を掲載させていただきます。 typedef struct __node{ int data; struct __node *next; }Node; ... /*リストの尻にノードを追加する関数 * 引数: head. リストの先頭ノードのポインタ data. リストの尻に追加したいint型の変数*/ void Insert_Tail(Node *head, int data) { Node *ptr = head; if(ptr == NULL){ /*<ノードが存在しない時には追加されない>*/ /*領域の確保*/      head = (Node*)calloc(1,sizeof(Node)); /*データをセット*/ head->data = data; head->next = NULL; return ; }else{ /*<ノードが存在するときには正常に動作>*/ while(ptr->next != NULL){ ptr = ptr->next; } /*領域の確保*/ ptr->next = (Node*)calloc(1,sizeof(Node));      /*データのセット*/ ptr->next->data = data; ptr->next->next = NULL; } } コメントアウトにも書かせていただきましたが、ノードがすでに存在するときには、正常にノードの最後に追加してくれるのですが、ノードが存在しない時にはリストに追加してくれません。 どうかご指導、ご指摘の程お願いします。

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

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

    線形リストのコードでどーしても理解できない個所があります。 (以下、コード部分) 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の基本的な部分(ポインタも含めて)については充分に理解しているつもりです。 どなたか御教授頂けないでしょうか。 長々と書いてしまいましたがよろしくお願いします。

  • 双方向リストで…、

    typedef struct score{ char name[40]; int eng; int math; int sci; struct score *next; struct score *prev; } SCORE; SCORE head; /* 双方向リストに要素を追加する */ void add_list(void) { SCORE *p, *new; in_file = fopen("input.txt", "r"); if ( in_file == NULL ){ printf("error: not open file.\n"); exit(0); } while( fgets(line, sizeof(line), in_file) != NULL ){ p = head.next; /* 先頭要素の次の要素のアドレス */ /* 新しく追加する要素のためのメモリ領域を確保する */ new = malloc( sizeof(SCORE) ); /* 新しい要素のデータを設定 */ sscanf(line, "%s %d %d %d", new->name, &new->eng, &new->math, &new->sci); new->next = p->next; /* 新しい要素の次の要素へのアドレスを設定 */ new->prev = p; /* 新しい要素の前の要素へのアドレスを設定 */ p->next->prev = new; /* 新しい要素の直後の要素のprevに、新しい要素のアドレスを設定 */ p->next = new; /* 新しい要素の直前の要素のnextに、新しい要素のアドレスを設定 */ } } ↑のところがうまくいきません。 何がだめか教えてください。

  • C言語 アロー演算子について質問です。

    こんにちわ C言語初心者です。 C言語の教科書を見ていたら 双方向リストへの挿入というところで struct CELL{ struct CELL *prev; struct CELL *next; int value; } x->prev=p; x->next=p->next; p->next->prev=x; p->next=x; という記述がありました。 質問はこの部分で p->next->prev=x; アロー演算子が2個つくとどうなるんですか? 出来ればこの双方向リストの例でたとえてもらえるとうれしいです。 よろしくお願いします。

  • リスト構造を使ってSortとSearchをするプログラム

    タイトルのとおりのプログラムを組んでみました ----------himajin.c----------- #include <stdio.h> #include <string.h> #include <stdlib.h> // 参考:http://www9.plala.or.jp/sgwr-t/c/sec15-5.html // コンパイラ:BCC 5.5 // アイテムの加え方が違う。 struct Item { int data; /* データ */ struct Item *next; /* 次のデータへのポインタ */ }; struct Item *head; struct Item *tail; struct Item *addItem(struct Item *p,int newdata){ struct Item *t; t->data = newdata; t->next = tail; p->next = t; return t; } int main(){ struct Item *item; int inputdata; head = item; item->next = tail; while (scanf("%d", &inputdata) != EOF) { item = addItem(item,inputdata); } /* search(5); sort(); */ return 0; } int sort(){ struct Item *j; struct Item *p; struct Item *t; p = head; t = head; while (p->next != tail){ while (p->data > t->data){ j = t; t = t->next; } j->next = p; p->next = t; p = p->next; } } int search(int searchdata){ struct Item *t; t = head; tail->data = searchdata; while (searchdata != t->data){ t = t->next; } if(t == tail){ printf("Not Found"); } else{ printf("Found"); /*後で考える*/ } return 0; } ---- ...が、コマンドラインで himajin.exe 5 と入力してみたところ、いきなりプログラムが落ちました。何がいけないのでしょうか?

  • 構造体のポインタ

    なぜかprevのほうが表示されません。 問題としては関数を作成し gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END と表示させるのが目的です gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] ここまではうまく表示できているのですが・・・ #include <stdio.h> void printoufuku(struct kara *p); struct kara { char name[16]; int age; struct kara *next; struct kara *prev; }; int main() { struct kara a, x, f, m, c, *start; strcpy(a.name, "gyuri"); a.age = 23; strcpy(x.name, "sunyon"); x.age = 23; strcpy(f.name, "nicole"); f.age = 20; strcpy(m.name, "hara"); m.age = 20; strcpy(c.name, "jiyon"); c.age = 17; a.next = &x; x.next = &f; f.next = &m; m.next = &c; c.next = NULL; /********************* 5 lines */ c.prev = &m; m.prev = &f; f.prev = &x; x.prev = &a; a.prev = NULL; /*********************/ start = &a; printoufuku(start); return 0; } void printoufuku(struct kara *p) { for(p->next; p != NULL;p = p->next){ printf("%s[%d] ->",p->name,p->age); } for(p->prev; p != NULL; p = p->prev){ printf("%s[%d] ->",p->name,p->age); } }