# 2020q3 Homework1 (quiz1)
contributed by < `carlhutant` >
```c=1
#include <stdio.h>
#include <stdlib.h>
typedef struct __node {
int value;
struct __node *next;
} node_t;
```
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
example [label="{<value> value| <next> next}"]
}
```
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
藍色為 main 中的 head
```c=8
void add_entry(node_t **head, int new_value)
{
node_t **indirect = head;
```
傳入的是 main 中 head 的 address
因此 :
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> head:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
藍色為 head
紅色為 indirect
```c=11
node_t *new_node = malloc(sizeof(node_t));
new_node->value = new_value;
new_node->next = NULL;
```
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
new_node [label="{<value> new_value| <next>NULL }"][color=darkgreen];
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> head:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
綠色為 new_node
```c=14
AA1;
```
==(a) assert(new_node) 大概有確認 malloc 是否完成的功能==
==(b) *indirect = new_node==
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
new_node [label="{<value> new_value| <next>NULL }"][color=darkgreen];
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnew_node}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> head:value;
head:next -> 72:value[style="dashed"][color=grey];
head:next -> new_node:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
改動了 head 紀錄的 address
因此 (a) 較恰當
```c=15
while (*indirect)
indirect = &(*indirect)->next;
```
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> head:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
step1:
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nnext of 72}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> 72:next;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
step2:
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nnext of 101}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> 101:next;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
step3:
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nnext of 108}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> 108:next;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
```c=17
AA2;
```
==(a) assert(new_node) 確認 malloc 是否完成==
==(b) *indirect = new_node==
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nnext of 108}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> 108:next;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
NULL 換成 address of new_node
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nnext of 108}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next> address of new_node }"];
new_node [label="{<value> new_value| <next>NULL }"][color=darkgreen];
indirect -> 108:next;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
108:next -> new_node:value;
}
```
因此選 (b)
```c=18
}
node_t *find_entry(node_t *head, int value)
{
node_t *current = head;
for (; current && current->value != value; current = current->next)
/* interate */;
return current;
}
void remove_entry(node_t **head, node_t *entry)
{
node_t **indirect = head;
while ((*indirect) != entry)
indirect = &(*indirect)->next;
*indirect = entry->next;
free(entry);
}
node_t *swap_pair(node_t *head)
{
for (node_t **node = &head; *node && (*node)->next; BB1) {
node_t *tmp = *node;
```
建立 tmp 綠色
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
tmp [label="{<next> address of\nnode 72}"][color=darkgreen]
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
tmp -> 72:value
indirect -> head:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
```c=43
BB2;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
```
要完成共三項 :
1.藍色 head 指向 101
2.72 的 next 指向 108
3.101 的 next 指向 72
2. 與 3. 分別在 44 與 45 完成了 (從 tmp 可看出)
因此 BB2 要將
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
tmp [label="{<next> address of\nnode 72}"][color=darkgreen]
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
tmp -> 72:value
indirect -> head:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
轉成
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
tmp [label="{<next> address of\nnode 72}"][color=darkgreen]
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 101}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
tmp -> 72:value
indirect -> head:value;
head:next -> 101:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
==( a ) node = (*node)->next==
==( b ) node = &(*node)->next==
==( c ) *node = (*node)->next==
==( d ) *node = &(*node)->next==
==( e ) *node = &((*node)->next)==
選 ( c ) *node = (*node)->next
可知交換完後會是 :
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
tmp [label="{<next> address of\nnode 72}"][color=darkgreen]
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 101}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 108}"];
101 [label="{<value> 101| <next> address of\nnode 72}"];
108 [label="{<value> 108| <next>NULL }"];
tmp -> 72:value
indirect -> head:value;
head:next -> 101:value;
72:next -> 108:value;
101:next -> 72:value;
}
```
下一輪開始前必須轉成 :
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
indirect [label="{<next> address of\nhead}"][color=red];
head [label="{<next> address of\nnode 101}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 108}"];
101 [label="{<value> 101| <next> address of\nnode 72}"];
108 [label="{<value> 108| <next>NULL }"];
indirect -> 72:next;
head:next -> 101:value;
72:next -> 108:value;
101:next -> 72:value;
}
```
因此 BB1
==( a ) node = (*node)->next->next==
==( b ) *node = (*node)->next->next==
==( c ) *node = ((*node)->next)->next==
==( d ) *node = &((*node)->next)->next==
==( e ) node = &(*node)->next->next==
==( f ) *node = &(*node)->next->next==
選(e)
```c=47
return head;
}
node_t *reverse(node_t *head)
{
node_t *cursor = NULL;
while (head) {
node_t *next = head->next;
```
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
cursor [label="{<next> NULL}"][color=darkgreen]
next [label="{<next> address of\nnode 101}"][color=red];
head [label="{<next> address of\nnode 72}"][color=blue];
72 [label="{<value> 72| <next> address of\nnode 101}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
next -> 101:value;
head:next -> 72:value;
72:next -> 101:value;
101:next -> 108:value;
}
```
藍色為 head
紅色為 next
綠色為 cursor
因為 72 的 next 必須改為 NULL 所以才發現 cursor 應該是指向每個 next 要改成的目標
而 head 為要修改的 node
最後變成 :
```graphviz
digraph add_entry{
rankdir=LR;
node [shape=record];
cursor [label="{<next> address of\nnode 72}"][color=darkgreen]
next [label="{<next> address of\nnode 108}"][color=red];
head [label="{<next> address of\nnode 101}"][color=blue];
72 [label="{<value> 72| <next> NULL}"];
101 [label="{<value> 101| <next> address of\nnode 108}"];
108 [label="{<value> 108| <next>NULL }"];
cursor -> 72:value;
next -> 108:value;
head:next -> 101:value;
72:next -> 101:value[color=grey][style="dashed"];
101:next -> 108:value;
}
```
==( a ) cursor = head; head->next = cursor==
==( b ) head->next = cursor; cursor = head==
==( c ) cursor = head==
==( d ) head->next = cursor==
==( e ) head->next->next = cursor; cursor->next = head==
==( f ) cursor->next = head; head->next->next = cursor==
因此選 (b)
```c=55
CCC;
head = next;
}
return cursor;
}
```
改變指標操作方式的 swap_pair 和 reverse :
```c=1
void swap_pair(node_t **head)
{
for (node_t **node = head; *node && (*node)->next; node=&(*node)->next->next) {
node_t *tmp = *node;
*node=(*node)->next;
tmp->next = (*node)->next;
(*node)->next = tmp;
}
}
void reverse(node_t **node)
{
node_t *cursor = NULL;
while (*node) {
node_t *next = (*node)->next;
(*node)->next = cursor;
cursor = *node;
*node = next;
}
*node=cursor;
}
```
以遞迴改寫的 reverse :
```c=1
void rev_recursive(node_t **node, node_t *cursor)
{
if(*node){
node_t *next = (*node)->next;
(*node)->next = cursor;
cursor = *node;
*node = next;
rev_recursive(node,cursor);
}
else{
*node = cursor;
}
}
void reverse(node_t **node)
{
node_t *cursor = NULL;
rev_recursive(node,cursor);
}
```
```c=60
void print_list(node_t *head)
{
for (node_t *current = head; current; current = current->next)
printf("%d ", current->value);
printf("\n");
}
int main(int argc, char const *argv[])
{
node_t *head = NULL;
print_list(head);
add_entry(&head, 72);
add_entry(&head, 101);
add_entry(&head, 108);
add_entry(&head, 109);
add_entry(&head, 110);
add_entry(&head, 111);
print_list(head);
node_t *entry = find_entry(head, 101);
remove_entry(&head, entry);
entry = find_entry(head, 111);
remove_entry(&head, entry);
print_list(head);
/* swap pair.
* See https://leetcode.com/problems/swap-nodes-in-pairs/
*/
head = swap_pair(head);
print_list(head);
head = reverse(head);
print_list(head);
return 0;
}
```
實作 Fisher–Yates shuffle:
```c=1
void FYShuffle(node_t **head){
srand(time(NULL));
node_t **node=head;
int num=0;
while(*node){
num++;
node=&(*node)->next;
}
for(int i=num;i>0;i--){
int pos=rand()%i+num-i;
node=head;
for(int j=0;j<pos;j++){
node=&(*node)->next;
}
node_t *tmp=*node;
*node=(*node)->next;
tmp->next=*head;
*head=tmp;
}
}
```