C言語関係掲示板

過去ログ

No801 双方向リスト

[戻る] [ホームページ]
No.10031

双方向リストの連結(?)
投稿者---teenager(2003/10/26 05:34:13)


双方向リストを作っているんですが、
過去ログに双方向リストの並び替え・・ってのがあったんですけど
それ見てもリストのつなげ方がいまいちわかりません。
ちょっと自分で考えたのがあるんですけど見てください。

//データを入れる構造体
struct dat{
   char a[10];
   char b[10];
};

//リストを構成するセル
struct cell{
   struct dat *elem;//要素
   struct cell *pre;//前のセルへ
   struct cell *next;//次のセルへ
};


こういう場合に双方向リストを作りたいんですけど

main(){
  ・・・

  d = MyRead();//構造体にデータを入れる関数
  MyList(d,c);

}

//リストを作る関数
MyList(struct dat *d,struct cell *c){
  struct cell *k

   ・・・・  //データdをセルcの要素にコピーする

//リストの連結?(この辺りがわからない)
  c->next = k;
  k->pre = c;
  k->next = NULL;
}

こんな感じだと思ってやったんですけど
c->next = k;
k->pre = c;
k->next = NULL;
これって間違いですかね?
ちょっとわけありでいろいろ省略して
書いているのでわかりにくいかと思いますが
どうかおしえてください。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:双方向リストの連結(?) 10032 RAPT 2003/10/26 10:21:52


No.10032

Re:双方向リストの連結(?)
投稿者---RAPT(2003/10/26 10:21:52)


省略しすぎです。コンパイル可能なソースを提示してください。
ソースを添付する際には「HTML変換ツール」で字下げしてください。(コピペ)
Windows2000sp4/VC++6sp5で動作確認済み

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

//データを入れる構造体
struct dat{
  char a[10];
  char b[10];
};

//リストを構成するセル
struct cell{
  struct dat *elem; //要素
  struct cell *pre; //前のセルへ
  struct cell *next; //次のセルへ
};

//適当な値をセット
void MyRead(struct dat *d)
{
  static int num = 0;
  if (d == NULL)
    return;

  sprintf(d->a, "%d", num);
  sprintf(d->b, "%d", num * 10);
  num++;
}

//初期化処理
void init(struct cell **c, struct dat *d)
{
  if (*c == NULL){
    *c = malloc(sizeof(struct cell));
    if (*c == NULL)
      exit(1); // error
  }
  (*c)->elem = malloc(sizeof(struct dat));
  if ((*c)->elem == NULL){
    free(*c);
    exit(1); // error
  }
  *((*c)->elem) = *d;
  (*c)->next = (*c);
  (*c)->pre = (*c);
}

//リストを作る関数:右端に追加
void MyList(struct cell **c, struct dat *d)
{
  struct cell *k = NULL;
  init(&k, d);

  //リストの結合
  k->next = *c;
  k->pre = (*c)->pre;
  (*c)->pre->next = k;
  (*c)->pre = k;
  
}

void view(struct cell *c, int viewCount, int moveNext)
{
  int i;
  if (c != NULL){
    for (i = 0;i < viewCount; i++){
      printf("\t %s \t %s\n", c->elem->a, c->elem->b);
      if (moveNext != 0)
        c = c->next;
      else
        c = c->pre;
    }
  }
  printf("\n");
}

void term(struct cell *c)
{
  c->pre->next = NULL; //無限ループにならないようにするための配慮
  while(c != NULL){
    if(c->next == NULL){  /* 最後のノード */
      free(c->elem);
      c->elem = NULL;
      free(c);
      c = NULL;
    }else{
      c = c->next;  /* ポインタを次のノードに移動 */
      /* 注意:ここで順番を間違えると、次のノードの場所が不明になり、全部削除できなくなる */
      free(c->pre->elem);
      c->pre->elem = NULL;
      free(c->pre);  /* 前のノードを削除 */
      c->pre = NULL;
    }
  }
}

int main()
{
  struct dat d;
  struct cell *c = NULL;
  int i, size = 10;

  //初期化
  MyRead(&d); //構造体にデータを入れる関数
  init(&c, &d);

  for (i = 0; i < 3; i++){
    MyRead(&d); //構造体にデータを入れる関数
    MyList(&c, &d);
  }

  printf("左から%d個を表示 >>\n", size);
  view(c, size, 1);

  printf("右から%d個を表示 >>\n", size);
  view(c, size, 0);

  //後処理
  term(c);

  return 0;
}



この投稿にコメントする

削除パスワード