プロが教えるわが家の防犯対策術!

ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。
どうかお力添え願います。
#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;
}

A 回答 (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); /* ダミーを開放 */
}
    • good
    • 0
この回答へのお礼

メモリの解放のメソッドまで作成して頂いてありがとうございます。No1の方は不都合があるようなのでこちらを優先して参考させてもらいます。

お礼日時:2004/11/16 20:29

ノードを追加するごとに正しく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);
}

}
    • good
    • 0
この回答へのお礼

ありがとうございます。
なんとか考えて、一応自分で完成にこぎつけることができました。

お礼日時:2004/11/16 20:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!