Course
可以參考我做的課程簡報:
 Struct & Linked List
Struct
- tag
 
- member-list 
 
- variable list
 
1 2 3 4 5
   | struct <tag>{
  	member list      }variable list;
  | 
 
可以直接宣告
1 2 3 4 5 6 7 8 9 10
   | struct student{
    char name[5];   int age;    }st1, st2[100], *st3;
  int main(){    st1.age = 19; }
  | 
 
也可以另外宣告
1 2 3 4 5 6 7 8 9 10
   | struct student{
    char name[5];   int age;    };
  int main(){    struct student st1, st2[100], *st3; }
  | 
 
初始化
一般寫法
1 2 3 4
   | struct student st1;
  strcpy(st1.name, "LAVI"); st1.age = 19;
   | 
 
進階寫法,但不太會這樣寫
1 2 3 4 5 6
   | student st1={
    .name = "LAVI",   .age = 19,    };
  | 
 
直接選取運算子 .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | #include <stdio.h> #include <string.h>
  struct student{
      char name[5];     int age;    };
  int main(){          struct student st1;          strcpy(st1.name, "LAVI");     st1.age = 19;          printf("%s %d\n", st1.name, st1.age);          return 0; }
   | 
 
直接選取運算子 ->
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | #include <stdio.h> #include <string.h>
  struct student{
      char name[5];     int age;    };
 
  int main(){
      struct student st1;     struct student *st1Ptr = &st1;          strcpy(st1.name, "LAVI");     st1.age = 19;          printf("st1: %s %d\n", st1.name, st1.age);     printf("st1Ptr->: %s %d\n", st1Ptr->name, st1Ptr->age);     printf("(*st1Ptr): %s %d\n", (*st1Ptr).name, (*st1Ptr).age);     printf("&st1: %s %d\n", (&st1)->name, (&st1)->age);          return 0; }
   | 
 
Lab 0x0
小明是一位程式設計老師
他總共有 n 個學生、這學期考了 m 次上機考
今天小明想要當掉全班 1/2 個學生 你能幫他找出誰會被當嗎 owo
1 2 3 4 5 6
   | 4                   <- 學生人數 (row) 5                   <- 考試次數 (column) Tom 99 80 75 88 92  <- 名字&分數 Ann 88 72 60 77 72 Bee 60 55 44 88 99 Amy 99 99 99 99 99
   | 
 
Output
1 2
   | Ann 88 72 60 77 72 Bee 60 55 44 88 99
   | 
 
Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
   | #include <stdio.h>
  struct Student{
      char name[10];     int scores[10];     int totalscore;
  }student[65];
  int main(){
      int n, m;     int average = 0;     scanf("%d%d", &n, &m);
      for(int i = 0 ; i < n ; i++){         scanf("%s", &student[i].name);
          for(int j = 0 ; j < m ; j++){             scanf("%d", &student[i].scores[j]);
              student[i].totalscore += student[i].scores[j];             average += student[i].scores[j];         }
      }     average /= n;     printf("\n");
      for(int i = 0; i < n; i++){
          if(student[i].totalscore < average){
              printf("%s ", student[i].name);             for(int j = 0; j < m; j++){                 printf("%d ", student[i].scores[j]);             }             printf("\n");         }     }
      return 0; }
   | 
 
Linked List
malloc
- memory allocation
 
- 配置指定大小的記憶體空間
 
- 動態的宣告記憶體空間
 
1 2 3 4 5 6
   | int *dyn;
  int arrlen1 = 5; int arrlen2 = 2;
  dyn = malloc( arrlen1 * arrlen2 * sizeof(int) );
   | 
 
free
- 釋放之前使用 malloc 所配置的記憶體空間
 
- memory leak
- 程式未釋放已不再使用的內部記憶體空間
 
- 用完記憶體後沒有 free 掉
 
 
- 在程式執行完後會自動把記憶體還回去
 
1 2 3 4 5 6
   | int *dyn;
  int arrlen1 = 5; int arrlen2 = 2;
  free(dyn);
   | 
 
用 struct 實作 linked list
1 2 3 4 5 6
   | struct node{
      int data;	              struct node *next;         }
  | 
 
創建一個 linked list 的 struct
1 2 3 4 5 6 7 8 9 10 11 12
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct struct list_node{
      char data[5];     list_pointer link;      }ListNode;
   | 
 
第一個節點
1 2 3 4 5 6 7 8 9 10 11
   | int main(){
      list_pointer ptr1 = NULL, ptr2 = NULL;          ptr1 = (list_pointer) malloc(sizeof(ListNode));          strcpy(ptr1->data, "CPC");     ptr1 -> link = NULL;          return 0; }
  | 
 
新增節點
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | list_pointer create2(){
  	list_pointer first, second;          first = (list_pointer) malloc(sizeof(ListNode));     second = (list_pointer) malloc(sizeof(ListNode));          second-> link = NULL;     strcpy(second->data, "Mimmy");     strcpy(first->data, "LAVI");     first-> link = second;          return first; }
  | 
 
Lab 0x1
給你一個字元陣列,請用迴圈把所有人依序串接起來
1
   | char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  | 
 
本題沒有輸入 Input
Output
1
   | CPC Jack Hank Jay Mimmy LAVI CHA yus Andy 
   | 
 
題示範例圖:

Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer link;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
 
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));
          strcpy(now->data, name[i]);         last->link = now;         last = now;     }     last->link = NULL;
      for(ListNode *i = head; i != NULL; i = i->link){         printf("%s ", i->data);     } }
   | 
 
Traverse
- 遍歷
 
- 每個點只記自己下一個點的位址 
 
- linked list 找點要遍歷,沒辦法像陣列直接取 index
 
1 2 3 4 5 6 7 8 9 10 11 12
   | int cnt = 0; ListNode *node = head;
  while(node->data != 5){
      cnt++;     node = node->link;
  } printf("%d\n", cnt);
 
 
   | 
 
Lab 0x2
來玩躲貓貓 !
請找到 LAVI 排在整段鏈結串列中的第幾個
Tips: 請從 0 開始算哦

Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer link;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
 
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));
          strcpy(now->data, name[i]);         last->link = now;         last = now;     }     last->link = NULL;
      int cnt = 0;     ListNode *node = head;          while(strcmp(node->data, "LAVI")){
          cnt++; 	    node = node->link;          }     printf("%d\n", cnt); }
   | 
 
Insertion
- 插入
 
- 遍歷找到要插入新節點的位址 
 
- 更改前一節點的 link -> 新節點
 
- 將新節點的 link 指向原位址的節點
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | list_pointer insert; insert = (list_pointer) malloc(sizeof(ListNode));
  insert->data = 9;
 
  list_pointer node = head;
  while(node->data != 4){     node = node->link;   }
  insert->link = node->link; node->link = insert;
   | 
 
Lab 0x3
歡迎加入 CPC 的行列 owo
試著把你的名字接在 Mimmy 學姊和 LAVI 之間並輸出
本題沒有輸入 Input
Output
1
   | Jack Hank Jay Mimmy <你的名字> LAVI CHA yus Andy
   | 
 
Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer link;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
 
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));
          strcpy(now->data, name[i]);         last->link = now;         last = now;     }     last->link = NULL;
      list_pointer insert;     insert = (list_pointer) malloc(sizeof(ListNode));
      strcpy(insert->data, "ShinHung");     insert->link = NULL;
      list_pointer node = head;     while(strcmp(node->data, "Mimmy")){
          node = node->link;              }     insert->link = node->link;     node->link = insert;
      for(ListNode *i = head; i != NULL; i = i->link){         printf("%s ", i->data);     } }
   | 
 
Deleting
- 刪除節點
 
- 遍歷找到要刪除節點的位址 
 
- 更改前一節點的指標 -> 下一節點
 
- free 歸還被刪除之節點的記憶體空間
 
1 2 3 4 5 6 7 8 9 10 11
   | list_pointer edge = head, ptr = edge;      while(ptr->data != 9){
  	edge = ptr; 	ptr = ptr->link;      }
  edge->link = ptr->link; free(ptr);
   | 
 
Lab 0x4
現在試試來把你自己刪掉 !
或是要刪其他人也可以啦 owo
本題沒有輸入 Input
Output
1
   | Jack Hank Jay Mimmy LAVI CHA yus Andy
   | 
 
Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer link;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
 
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));
          strcpy(now->data, name[i]);         last->link = now;         last = now;     }     last->link = NULL;
      list_pointer insert;     insert = (list_pointer) malloc(sizeof(ListNode));
      strcpy(insert->data, "ShinHung");     insert->link = NULL;
      list_pointer node = head;     while(strcmp(node->data, "Mimmy")){
          node = node->link;              }     insert->link = node->link;     node->link = insert;
      list_pointer edge = head, ptr = edge;          while(strcmp(ptr->data, "ShinHung")){         edge = ptr;         ptr = ptr->link;     }     edge->link = ptr->link;     free(ptr);
      for(ListNode *i = head; i != NULL; i = i->link){         printf("%s ", i->data);     } }
   | 
 
Circularly
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | ListNode *head = NULL; head = malloc(sizeof(ListNode));
  head->data = 0;
  ListNode *last = head, *now;
  for(int i = 1; i < 9; i++){
    now = malloc(sizeof(ListNode));
    now->data = i;   last->link = now;   last = now;
  }
  last->link = head;
   | 
 
Lab 0x5
把鏈結串列頭尾連起來 讓大家停不下來 !
Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node* list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer link;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
 
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));
          strcpy(now->data, name[i]);         last->link = now;         last = now;     }     last->link = head;
      for(ListNode *i = head; i != NULL; i = i->link){         printf("%s ", i->data);     }     printf("\n\n");      }
   | 
 
Doubly Linked List
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | typedef struct list_node *list_pointer;
  typedef struct list_node{     int data;     list_pointer leftlink;     list_pointer rightlink; }ListNode;
  ListNode *head = NULL; head = malloc(sizeof(ListNode));
  head->data = 0; head->leftlink = NULL;
  ListNode *last = head, *now;
  for(int i = 1; i < 9; i++){   now = malloc(sizeof(ListNode));   now->data = i;
    last->rightlink = now;   now->leftlink = last;   last = now; } last->rightlink = NULL;
   | 
 
Insertion
- 插入
- 遍歷找到要插入新節點的位址 
 
- 前一節點的右指標 -> 新節點
 
- 新節點的左指標 -> 前一節點
 
- 新節點的右指標 -> 下一節點
 
- 下一節點的左指標 -> 新節點
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | list_pointer insert; insert = (list_pointer) malloc(sizeof(ListNode));
  insert->data = 9;
  list_pointer node = head, ptr = head;
  while(ptr->data != 3){   node = ptr;   ptr = ptr->rightlink;   }
  insert->rightlink = node->rightlink; node->rightlink->leftlink = insert;
  insert->leftlink = node; node->rightlink = insert;
   | 
 
Deleting
- 刪除
- 遍歷找到要刪除節點的位址 
 
- 前一節點的右指標 -> 被刪除節點之下一節點
 
- 下一節點的左指標 -> 前一節點
 
- free 歸還被刪除之節點的記憶體空間
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13
   | list_pointer edge = head, pt = edge;          while(pt->data != 9){
    edge = pt;   pt = pt->rightlink;
  }
  edge->rightlink = pt->rightlink; pt->rightlink->leftlink = edge;
  free(pt);
   | 
 
Lab 0x6
把大家手牽手左右牽起來~
本題沒有輸入 Input
Output
1 2 3 4 5
   | from begining to end CPC Jack Hank Jay Mimmy LAVI CHA yus Andy
  from end to begining Andy yus CHA LAVI Mimmy Jay Hank Jack CPC
   | 
 
Solution Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
   | #include<stdio.h> #include<stdlib.h> #include<string.h>
  typedef struct list_node *list_pointer;
  typedef struct list_node{
      char data[10];     list_pointer leftlink;     list_pointer rightlink;      }ListNode;
  char name[][10] = {"Jack", "Hank", "Jay", "Mimmy", "LAVI", "CHA", "yus", "Andy"};
  int main(){
      ListNode *head = NULL;     head = malloc(sizeof(ListNode));
      strcpy(head->data, "CPC");     head->leftlink = NULL;
      ListNode *last = head, *now;
      for(int i = 0; i < 8; i++){
          now = malloc(sizeof(ListNode));         strcpy(now->data, name[i]);
          last->rightlink = now;         now->leftlink = last;         last = now;     }     last->rightlink = NULL;
      printf("from begining to end\n");     for(ListNode *i = final; i != NULL; i = i->rightlink){         printf("%s ", i->data);     }
      printf("\n\nfrom end to begining\n");     for(ListNode *i = last; i != NULL; i = i->leftlink){         printf("%s ", i->data);     } }
   | 
 
UVA Problem
 UVA 11988 - Broken Keyboard