単方向リスト

# 単方向リストの課題やったときのメモ

#課題１
```c:kadai1.c
#include<stdio.h> // 標準入出力
#include<stdlib.h> // 動的なメモリの作成

#define NUM 4

// 単方向リストの構造体
typedef struct cell {
  int val; // int型:セルの値を格納
  struct cell * next; // 構造体への自己参照型
} CELL;


// プロトタイプ宣言
void addList(CELL *list, int val);
void printList(CELL *list);

// main関数
int main(void) {
  int i; // カウンタ
  int data[NUM] = {5, 10, 15, 20}; // データ
  CELL first_cell; // リストの先頭

  printf("プログラムの実行\n");

  // 単方向リストをつくる
  for(i=0;i<NUM;i++) {
    addList(&first_cell, data[i]);
  }

  // 表示
  printList(&first_cell);

  return 0;
}

// 単方向リストを作る関数
void addList(CELL *list, int val) {

  // 新しい項目をつくるnew[[val , NULL]]-------------------------

  CELL *new; // 新規確保用
  new = (CELL*)malloc(sizeof(CELL)); // 新しいリストの領域を確保
  new->val = val; // 値を代入
  new->next = NULL; // 次の要素は末尾とわかるようにNULLを入れとく
  // ------------------------------------------------------------


  // list は最初、先頭の項目を指している-------
  // (はじめ)
  //  v
  // [32]->[229]->[2]->[59]->[NULL]

  // 以下のwhile文は、
  // 最後の項目になるまでlistを移動していく
  //                   (ここ)
  //                    v
  // [32]->[229]->[2]->[59]->[NULL]
  while(list->next!=NULL) {
    list = list->next;
  }
  // ----------------------------------------


  // 最後の項目の後に[NEW!!]->[NULL]を追加---
  //
  // [32]->[229]->[2]->[59]->[NEW!!]->[NULL]
  list->next = new;
  // ----------------------------------------
}


// 単方向リストを表示する関数
void printList(CELL *list) {

  // 項目の中に次へのアドレスが入っているときは表示させる
  while(list->next != NULL) {
    // main関数で何も入っていないfirst_cellを宣言しているので2個目から表示-------
    // 
    // (はじめ)
    //  v
    // [?]->[32]->[229]->[2]->[59]->[NULL]
    list = list->next;
    printf("%d\n", list->val); // 表示
    // ---------------------------------------------------------------
  }

}

```
#課題2
```c:kadai2.c
#include<stdio.h> // 標準入出力
#include<stdlib.h> // 動的なメモリの作成

// 単方向リストの構造体
typedef struct cell {
  int val; // int型:セルの値を格納
  struct cell * next; // 構造体への自己参照型
} CELL;


// プロトタイプ宣言
void addList(CELL *list, int val);
void printList(CELL *list);

// main関数
int main(void) {
  int data=1;
  CELL first_cell; // リストの先頭

  printf("プログラムの実行\n");

  // 単方向リストをつくる
  while(data) {
    printf("データを入力してください:");
    scanf("%d", &data);
    addList(&first_cell, data);
  }

  // 表示
  printList(&first_cell);

  return 0;
}

// 単方向リストを作る関数
void addList(CELL *list, int val) {

  // 新しい項目をつくるnew[[val , NULL]]-------------------------

  CELL *new; // 新規確保用
  new = (CELL*)malloc(sizeof(CELL)); // 新しいリストの領域を確保
  new->val = val; // 値を代入
  new->next = NULL; // 次の要素は末尾とわかるようにNULLを入れとく
  // ------------------------------------------------------------


  // list は最初、先頭の項目を指している-------
  // (はじめ)
  //  v
  // [32]->[229]->[2]->[59]->[NULL]

  // 以下のwhile文は、
  // 最後の項目になるまでlistを移動していく
  //                   (ここ)
  //                    v
  // [32]->[229]->[2]->[59]->[NULL]
  while(list->next!=NULL) {
    list = list->next;
  }
  // ----------------------------------------


  // 最後の項目の後に[NEW!!]->[NULL]を追加---
  //
  // [32]->[229]->[2]->[59]->[NEW!!]->[NULL]
  list->next = new;
  // ----------------------------------------
}


// 単方向リストを表示する関数
void printList(CELL *list) {

  // 項目の中に次へのアドレスが入っているときは表示させる
  while(list->next != NULL) {
    // main関数で何も入っていないfirst_cellを宣言しているので2個目から表示-------
    //
    // (はじめ)
    //  v
    // [?]->[32]->[229]->[2]->[59]->[NULL]
    list = list->next;
    printf("%d\n", list->val); // 表示
    // ---------------------------------------------------------------
  }

}

```
# 課題3
```c:kadai3.c
#include<stdio.h> // 標準入出力
#include<stdlib.h> // 動的なメモリの作成

// 単方向リストの構造体
typedef struct cell {
  int val; // int型:セルの値を格納
  struct cell * next; // 構造体への自己参照型
} CELL;


// プロトタイプ宣言
void addList(CELL *list, int val);
void printList(CELL *list);
void freememory(CELL *list);

// main関数
int main(void) {
  int i; // カウンタ
  int data=1;
  CELL end_cell = {100, NULL}; // リストの最後
  CELL first_cell = {0, &end_cell}; // リストの先頭


  printf("プログラムの実行\n");

  // 単方向リストをつくる
  while(data) {
    printf("データを入力してください:");
    scanf("%d", &data);
    if(data < 1 || data > 99)
      break;
    addList(&first_cell, data);
  }

  // 表示
  printList(&first_cell);

  // メモリの開放
  freememory(&first_cell);

  return 0;
}


// メモリ解放用関数
void freememory(CELL *list) {
  CELL * tmp;

  list = list->next;
  while(list->next != NULL) {
    tmp = list;
    list = tmp->next;

    free(tmp);
  }
}

// 単方向リストを作る関数
void addList(CELL *list, int val) {

  // 新しい項目をつくるnew[[val , NULL]]-------------------------

  CELL *new; // 新規確保用
  new = (CELL*)malloc(sizeof(CELL)); // 新しいリストの領域を確保
  new->val = val; // 値を代入
  new->next = NULL; // 次の要素は末尾とわかるようにNULLを入れとく
  // ------------------------------------------------------------


  // list は最初、先頭の項目を指している-------
  // (はじめ)
  //  v
  // [32]->[229]->[2]->[59]->[NULL]

  // 以下のwhile文は、
  // 最後の項目になるまでlistを移動していく
  //                   (ここ)
  //                    v
  // [32]->[229]->[2]->[59]->[NULL]
  while((list->next)->val < val) {
    list = list->next;
  }
  // ----------------------------------------


  // 最後の項目の後に[NEW!!]->[NULL]を追加---
  //
  // [32]->[229]->[2]->[59]->[NEW!!]->[NULL]
  new->next = list->next;
  list->next = new;
  // ----------------------------------------
}


// 単方向リストを表示する関数
void printList(CELL *list) {

  // 項目の中に次へのアドレスが入っているときは表示させる
  while(list->next != NULL) {
    // main関数で何も入っていないfirst_cellを宣言しているので2個目から表示-------
    //
    // (はじめ)
    //  v
    // [?]->[32]->[229]->[2]->[59]->[NULL]
    // list = list->next;
    printf("%d\n", list->val); // 表示

    list = list->next;
    // ---------------------------------------------------------------
  }
  printf("%d\n", list->val); // 表示
}

```