双方向リストの辿りかたについての質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Toshita
記事: 23
登録日時: 8年前

双方向リストの辿りかたについての質問

#1

投稿記事 by Toshita » 8年前

入力された整数を双方向リストを用いて順次格納する。
この時、リストに格納されていない整数のみをリストの最期に追加するようにする。
0が入力された時に整数の入力を終了し、それまでに格納された全ての整数を表示するプログラム。※表示は,順方向,逆方向順で行う。

という内容のプログラムなのですが、友人のと比較して処理がどう違うのかよくわからないです。
僕は自分が作ったことのある双方向リストをイジッただけなのですが、どうやら辿りかたや入力のしかたが違うようで無駄が多いうえに、出力も逆順→順の順番で表示してしまいます。
どこをどう改善すればいいでしょうか?

INPUT : 10 20 10 30 20 0 (0で終了)
OUTPUT : 10 20 30 30 20 10

コード:

/*自分のプログラム*/
#include<stdio.h>
#include<stdlib.h>

struct list{
	int no;
	struct list *prev;
	struct list *next;
};
struct list head;

int help(int n,struct list *new){
	int i=1;
	new = head.next;			/*ノードを先頭に*/
	while(new != NULL){
		if(n == new->no){
			i--;
			break;
		}
		new = new->next;
	}
	return i;
}

int main(void)
{
	struct list *new;			/*ノードの保管用*/
	int n,m,i=0;				/*データの取得*/
	
	
	scanf("%d",&n);
        /*エラー処理*/
        new = (struct list*)malloc(sizeof(struct list));
        if(new == NULL){
        	printf("error\n");
        	return;
        }
        new->no = n;                    /*データの設定*/
        
	new->next = head.next;          /*リストに追加*/
        head.next = new;                /*同上*/
        new->prev = &head;
	m = n;
	
	do{
		scanf("%d",&n);
		/*エラー処理*/
		new = (struct list*)malloc(sizeof(struct list));
		if(new == NULL){
			printf("error\n");
			return;
		}
		if(help(n,new)){
			new->no = n;			/*データの設定*/
			
			new->next = head.next;		/*リストに追加*/
			head.next->prev =new;
			new->prev = &head;
			head.next = new;		/*同上*/
		}
		
	}while(n != 0);
	
	new->no = n;
	new = new->next;
		
	/*表示*/
	while(new->no != m){
		printf("%d\n",new->no);
		new = new->next;
		i++;
	}
	printf("%d\n",new->no);	//切り返し分の足りない分の表示
	while(i != 0){
		printf("%d\n",new->no);
		new = new->prev;
		i--;
	}
	printf("%d\n",new->no);
	return 0;
}

コード:

/*友人のプログラム*/
#include <stdio.h>
#include <stdlib.h>

struct CELL
{
    int a;
    struct CELL *next, *prev;
} header;

insert (int c)
{
    struct CELL *new, *p, *cur;

    p = &header;
    cur = p -> next;
    new = malloc(sizeof(struct CELL));

    while (cur != NULL) {
        p = p -> next;
        cur = cur -> next;
    }

    new -> a = c;
    new -> prev = p;
    p -> next = new;
    new -> next = NULL; 
}

pursue (void)
{
    struct CELL *cur, *p;

    p = &header;
    cur = p -> next;

    do{
        printf("%d\n",cur -> a);
        cur = cur -> next;
        p = p -> next;
    }while(cur != NULL);

    cur = p;
    p = p -> prev;

    do{
        printf("%d\n", cur -> a);
        cur = cur -> prev;
        p = p -> prev;
    }while(p != NULL);

}

int pursue1 (int c)
{
    struct CELL *cur, *p;

    p = &header;
    cur = p -> next;

    if(cur == NULL)
        return 0;

    else 
        while(cur != NULL){
            if(cur -> a == c)
                return 1;
            cur = cur -> next;
            p = p -> next;
        }
        return 0;
}

int main(void)
{
    int b;
    int i;

    header.next == NULL;
    header.prev == NULL;

    while(b != 0){
        scanf("%d", &b);
    
        if(b != 0){
            if(pursue1 (b) == 0)
                insert(b);
        }
    }
        pursue ();
}

non
記事: 1097
登録日時: 13年前

Re: 双方向リストの辿りかたについての質問

#2

投稿記事 by non » 8年前

あなたと友人との大きな違いは、head(友人のheader)の使い方の違いでしょう。友人の場合、1個もデータがない場合にheaderという数字が入っていないノードを1つ持っています。このようなものを、番兵もしくはSentinelといいます。これがあると、特別解(データが1個もないときや、最後のデータを消すときの処理など)を作らずにすむという利点があります。あなたも、headを番兵にしようとしているのだとは思いますが、意図が明確ではありません。

あなたのプログラムの大きな欠点は、headの初期化が明示的に行われていないことです。nextにはちゃんとNULLを入れておきましょう。また、関数helpの引数にstruct list *newは不要です。関数の中のiもわかりにくくしています。直接return 0;やreturn 1;の方がいいでしょう。
また、malloc でエラーが出たときの強制終了ですがこれも数値を返すようにしましょう。
友人のように、機能別に関数にするとプログラムを見てわかりやすいです。
non

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 双方向リストの辿りかたについての質問

#3

投稿記事 by みけCAT » 8年前

non さんが書きました:あなたのプログラムの大きな欠点は、headの初期化が明示的に行われていないことです。nextにはちゃんとNULLを入れておきましょう。
「友人のプログラム」でもheaderの初期化は明示的に行われていないですし、headはグローバル変数なので明示的に初期化しなければ自動的にゼロクリアされ、NULLが入ったことになるはずです。
そこまで大きな欠点でしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る