# 2020q3 Homework1 (quiz1) contributed by <OliveLake> - ==[Linked list 練習題](https://hackmd.io/@sysprog/sysprog2020-quiz1)== ### Q1:考慮一個單向 linked list,其結構定義為: ```c= typedef struct __node { int value; struct __node *next; } node_t; ``` 已知不存在 circular (環狀結構),接下來將對該單向 linked list 進行下列操作: #### 1.`add_entry`: 新增節點,當 linked list 沒有內容時,必須由開發者更新指向開頭的指標。因此實際得到 reference,而非 copy ```c= void add_entry(node_t **head, int new_value) { node_t **indirect = head; node_t *new_node = malloc(sizeof(node_t)); new_node->value = new_value; new_node->next = NULL; /* AA1 */ assert(new_node); while (*indirect) indirect = &(*indirect)->next; /* AA2 */ *indirect=new_node; } ``` assert()是用來除錯,如果參數是非零值則no action,若為零值則會終止程式。 AA1:選擇`assert(new_node)`是為了確定malloc有成功要到正確的記憶體 AA2:選擇`*indirect=new_node`,將indirect這個指標的值設給`new_node` #### 2.`swap_pair`:交換一對相鄰的節點,取自 [LeetCode: Swap Nodes in Pairs ](https://leetcode.com/problems/swap-nodes-in-pairs/),給定 1->2->3->4,則該回傳 2->1->4->3 ```cpp= node_t *swap_pair(node_t *head) { for (node_t **node = &head; *node && (*node)->next; /*BB1*/ node = &(*node)->next->next) { node_t *tmp = *node; /*BB2*/ *node = (*node)->next; tmp->next = (*node)->next; (*node)->next = tmp; } return head; } ``` BB1:選擇`node = &(*node)->next->next`,因為是兩兩交換,每次都要跳兩個node BB2:選擇`*node = (*node)->next;`,因為要對兩個node的`連接`做交換,所以是`*node` #### 3.`reverse:`將給定的 linked list 其內節點予以反向,即 1->2->3->4,則該回傳 4->3->2->1 ```cpp= node_t *reverse(node_t *head) { node_t *cursor = NULL; while (head) { node_t *next = head->next; /*CCC*/ head->next = cursor; cursor = head; head = next; } return cursor; } ``` CCC:選擇`head->next = cursor; cursor = head`,先宣告一個指標cursor,只要head不為NULL,就宣告一個指標next指向head的next,再將head的next指向cursor,cursor指向head,head再去指向下一個node,以實現反轉cursor的目的。