- ベストアンサー
(構造体)双方向連結リストの作成!
ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。 どうかお力添え願います。 #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ p -> left = tail; tail = p; } p = tail; head = NULL; while(p != NULL){ p -> right = head; head = p; p = p -> left; } head -> left = tail; p = head; printf("リスト表示\n"); while(p != NULL){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return 0; }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
No.1だとまったく入力がない時(いきなりCtrl+Zを入力した時)にheadが未定義、tailがNULLのままループ終了してしまうのでまずいですね。 参考まで、ダミーノード付きのプログラム(領域開放と入力文字数も考慮)を書いておきます。 #include<stdio.h> #include<stdlib.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void memfree(NODE *); int main(void) { NODE *head, *tail, *p; char buf[80]; /* 1行入力用 */ /* ダミー作成 */ if ((p = memalloc())==NULL) exit(1); head = tail = p->left = p->right = p; /* ノード入力 */ while(printf("名前 年齢入力(Ctrl + Zで終了)>"), fgets(buf, sizeof(buf), stdin) != NULL) { if ((p = memalloc())==NULL) { memfree(head); exit(1);} if (sscanf(buf,"%19s%5d", p->name, &p->age) != 2) { free(p); break;} tail -> right = p; p -> left = tail; /* pをtailとつなぐ */ head -> left = p; p -> right = head; /* pをheadとつなぐ */ tail = p; /* pは次のtail */ } /* 右回りに表示 */ p = head -> right; printf("リスト表示(右回り)\n"); while (p != head) { printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } /* 領域開放 */ memfree(head); return 0; } /* メモリ領域を確保する */ NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) == NULL){ printf("\n動的メモリ割当に失敗しました。\n"); } return ptr; } /* 確保したメモリ領域を開放する */ void memfree(NODE *head) { NODE *p, *pp; p = head->right; while ( p != head) { pp = p->right; /* 次のノードを一時的に保存 */ free(p); p = pp; } free(p); /* ダミーを開放 */ }
その他の回答 (1)
- kmb01
- ベストアンサー率45% (63/138)
ノードを追加するごとに正しくleftとrightを設定すればいい。 こんな感じだと思う。 void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ if (tail == NULL) { p->left = p->right = p; // 最初に作成したノードをheadにする。 head = tail = p; } else { // どんどん右に追加していく。新規ノードのleftはtailを指し、tailのrightは新規ノードを指す。 p->left = tail; tail->right=p; // tailを更新 tail = p; } } // headとtailをつなげて循環参照にする tail->right = head; head->left = tail; printf("リスト表示\n"); if (head) { p = head; do { printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; }while(p != head); } }
お礼
ありがとうございます。 なんとか考えて、一応自分で完成にこぎつけることができました。
お礼
メモリの解放のメソッドまで作成して頂いてありがとうございます。No1の方は不都合があるようなのでこちらを優先して参考させてもらいます。