ページ 11

リスト構造を用いたキューを実現するプログラム C言語

Posted: 2011年1月26日(水) 00:05
by shin
自分でプログラムを書いたのですが、どうも削除のところがうまく行きません。
何が間違っているのかいろいろサイトをみてまわったのですが、どうにもうまくいきません。
コンパイルは通り、実行もできますが、リスト削除を行うとリストの中身すべてが消えてしまいます。
最終的には、実行し、2を入力してから削除したい文字列を入力するとそこだけ削除されるというものです。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct wordlist{
char word[20];
struct wordlist *next;
};

void Print_List(struct wordlist element){ /* リスト表示 */

int i;
struct wordlist *p=element.next;
if(p==NULL){
printf("empty\n");
exit(1);
}
for(i=1;p->next!=NULL;i++){
printf("%2d %s\n",i,p->word);
p=p->next;
}
printf("%2d %s\n",i,p->word);
}

void Add_List(struct wordlist *head){ /* リスト追加 */
char Data[20];
struct wordlist *elem, *tmp;
elem = (struct wordlist *) malloc(sizeof(struct wordlist));
printf("Input strings: ");
scanf("%s",Data);

strcpy(elem->word,Data);
elem->next=NULL;

for(tmp=head; tmp->next!=NULL; tmp=tmp->next);
tmp->next=elem;
}

void Del_List(struct wordlist *head){ /* リスト削除 */
char Data[20];
struct wordlist *q, *r;
head->next=NULL;
q=head->next;
r=&head;

if(r == NULL) printf("empty\n");
return -1;

printf("Output strings: ");
scanf("%s",Data);

while(q != NULL && q->word!=Data){
r = q;
q = q->next; }

r->next = NULL;
free(q);
}

int main(void){
int i;
struct wordlist head, *elem;
char Data[20];
head.next=NULL;
for( ; ; ){
printf("Select: (1) Enqueue, (2) Dequeue , (0) Exit :");
scanf("%d", &i);

switch(i){
case 1:
Add_List(&head);
break;

case 2:
Del_List(&head);
break;

case 0:
Print_List(head);
break;
}


}
return 0;
}

Re: リスト構造を用いたキューを実現するプログラム C言語

Posted: 2011年1月26日(水) 00:50
by bitter_fox
shin さんが書きました:

コード:

void Del_List(struct wordlist *head){ /* リスト削除 */
	char Data[20];
	struct wordlist *q, *r;
	head->next=NULL;
	q=head->next;
	r=&head;

	if(r == NULL) printf("empty\n");
	return -1;

	printf("Output strings: ");
	scanf("%s",Data);

	while(q != NULL && q->word!=Data){
	r = q;
	q = q->next; }

	r->next = NULL;
	free(q);
}
実をいうと一件も削除されていません。

じゃあ、なぜ削除されているように見れるのかと言うと、

コード:

head->next = NULL;
のせいです。

プログラム全体を通して、先頭の次がNULLだったらデータがないと判断しているので、データがなくなったような実行結果になってしまったというわけです。

それから、

コード:

p->word != Data
と言うのは、p->wordのアドレスとDataのアドレスとを比較してるので、常に真になります。
文字列の比較を行うのであれば、strcmp関数を使いましょう。

[hr][追記]
コードを載せる際は、codeタグで囲っていただきますようにお願いします。
http://dixq.net/board/board.html#k10

Re: リスト構造を用いたキューを実現するプログラム C言語

Posted: 2011年1月26日(水) 01:20
by a5ua
qは削除対象のノード、rはその1つ前のノードを表していると思いますが、
r=&head;
これは、型が違います。
r=head;
とすべきでしょう。
if(r == NULL) printf("empty\n");
return -1;
これでは、常にreturn -1;が実行されますが、意図した動作ですか?
また、Del_List関数の型はvoidなので、return文を書くときは、
return;
とだけ書けばよいです。
r->next = NULL;
これでは、r以降のノードが全て消えたように見えてしまいます。
削除対象の1つ後ろのノードを指定しましょう。

また、削除対象が見つからなかった場合を考慮する必要があるでしょう。

Re: リスト構造を用いたキューを実現するプログラム C言語

Posted: 2011年1月26日(水) 01:36
by shin
>bitter_foxさん >a5uaさん

返信ありがとうございます!
お二方のご指摘をもとに、プログラムを書き直させて頂いたところ、うまく動作しました!
大変勉強になりました。ほんとうにどうもありがとうございますm(_ _)m