2009年7月26日

自己参照型(線形リスト)

線形リストを作成

-----------------------------------------queue.c
#include stdio.h
#include stdlib.h
#include string.h

/*-----メニュー-----*/
typedef enum{
  Term, /* 項目 */
  Insert, /* 先頭ノードに挿入 */
   Append, /* 末尾ノードに挿入 */
   Delete, /* 先頭ノードを削除 */
   Remove, /* 末尾ノードを削除 */
   Clear, /* 全ノード削除 */
   Print /* 出力 */
} Menu;

/*-----Node----*/
typedef struct __node{

  char name[20];
  char tel[16];

  struct __node *next;

} Node;


/*----線形リスト制御ブロック----*/
typedef struct {

  Node *head;
  Node *tail;

} List;


/*----一つのノードを確保----*/

Node *AllocNode(void){

  return ((Node *)calloc(1, sizeof(Node)));

}

/*----InitList----*/
void InitList(List *list){

  list->head = list->tail = AllocNode();

}

/*----InsertNode----*/
void InsertNode(List *list, const char *name, const char *tel){

  Node *ptr = list->head;

   list->head = AllocNode();
   strcpy(list->head->name, name);
   strcpy(list->head->tel, tel);
   list->head->next = ptr;

}

/*----AppendNode----*/
void AppendNode(List *list, const char *name, const char *tel){

   Node *ptr = list->tail;

   list->tail = AllocNode();
   strcpy(ptr->name, name);
   strcpy(ptr->tel, tel);
   ptr->next = list->tail;

}

/*----DeleteNode----*/
void DeleteNode(List *list){

   if(list->head !=list->tail){
      Node *ptr = list->head->next;
      free(list->head);
      list->head = ptr;
  }
}

/*----RemoveNode----*/
void RemoveNode(List *list){

   if(list->head != list->tail){
      if(list->head->next == list->tail){
         DeleteNode(list);
      }else{
         Node *curr, *prev;

         curr = list->head;
        while(curr->next != list->tail){
            prev = curr;
            curr = curr->next;
        }

        prev->next = list->tail;
        free(curr);
     }
  }
}

/*----ClearList----*/
void ClearList(List *list){

   Node *ptr = list->head;

   while(ptr != list->head){
      Node *ptr2 = ptr->next;
      free(ptr);
      ptr = ptr2;
   }

   list->head = list->tail;

}

/*----PrintList----*/

void PrintList(List *list){

  Node *ptr;

  ptr = list->head;

   while(ptr != list->tail){
      printf("%s <<%s>> \n", ptr->name, ptr->tel);
      ptr = ptr->next;
   }

}

/*----データ入力----*/
Node Read(char *message){

  Node temp;

  printf("%sするデータを入力して下さい。\n",message);

   printf("name:"); scanf("%s", temp.name);
   printf(" tel:"); scanf("%s", temp.tel);

   return(temp);
}

/*----メニュー選択----*/
Menu SelectMenu(void){

   int ch;

   do {
      puts("(1) 先頭にノードを挿入 (2)末尾にノードを挿入");
      puts("(3) 先頭のノードを削除 (4)末尾のノードを削除");
      puts("(5) 全てのノードの削除 (6)全てのノードを表示");
      puts("(0) 終了");
      printf("番号:"); scanf("%d", &ch);
   }while(ch <> Print);
   return((Menu)ch);
}

int main(void){

  Menu menu;
   List list;

  InitList(&list);

   do{
      Node x;
      switch(menu = SelectMenu()){

        case Insert: x = Read("先頭に挿入");
           InsertNode(&list, x.name, x.tel);      break;
        case Append: x = Read("末尾に挿入");
           AppendNode(&list, x.name, x.tel);     break;
        case Delete:DeleteNode(&list);           break;
        case Remove:RemoveNode(&list);        break;
        case Clear:ClearList(&list);              break;
        case Print:PrintList(&list);               break;
     }
   }while(menu != Term);

   ClearList(&list);
  return (0);
}


上記サンプルは
下記、参考書参照。
これいいよ^^




次回は循環リスト、双方向リストです。