# 2024q1 Homework2 (quiz1+2) contributed by < [tintinjian12999](https://github.com/tintinjian12999) > ## 第 1 週測驗題 [2024q1 第 1 週測驗題](https://hackmd.io/@sysprog/linux2024-quiz1) ### 測驗 `1` #### 解釋程式碼運行 在 ```c void quick_sort(node_t **list) ``` 中會將比 `pivot` 大的數存入 right 中,比 `pivot` 小或相等的數則存入 left 中 ```c while (p) { node_t *n = p; p = n->next; list_add(n->value > value ? &right : &left, n); } ``` 而 begin 與 end 則用 ```c //left, pivot, right begin[i], begin[i + 1], begin[i + 2] end[i], end[i + 1], end[i + 2] ``` 來儲存 left, pivot, right 節點的開頭與結尾 ```c begin[i] = left; end[i] = list_tail(left); begin[i + 1] = pivot; end[i + 1] = pivot; begin[i + 2] = right; end[i + 2] = list_tail(right); ``` 程式的執行過程如下 假設需排序的序列如下 ```graphviz digraph structs { node[shape=plaintext]; node[shape=box]; struct0 [label= "4"]; struct1 [label= "1"]; struct2 [label= "3"]; struct3 [label= "5"]; struct4 [label= "2"]; struct5 [label= "7"]; { rank="same"; struct0 -> struct1 struct1 -> struct2 struct2 -> struct3 struct3 -> struct4 struct4 -> struct5 } } ``` 則迭代過程為 ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 0\l"]; pivot left right node[shape=box]; struct0 [label= "4"]; struct1 [label= "1"]; struct2 [label= "3"]; struct3 [label= "5"]; struct4 [label= "2"]; struct5 [label= "7"]; { rank="same"; pivot -> struct0 } { rank="same"; left -> struct4 -> struct2 -> struct1 } { rank="same"; right -> struct3 -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 2\l"]; pivot left right node[shape=box]; struct3 [label= "5"]; struct5 [label= "7"]; NULL [label = "NULL"]; { rank="same"; pivot -> struct3 } { rank="same"; left -> NULL } { rank="same"; right -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 4\l"]; result [fontcolor="blue"]; node[shape=box]; struct5 [label= "7"] [fontcolor="blue"]; { rank="same"; result -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 3\l"]; result [fontcolor="blue"]; node[shape=box]; struct3 [label= "5"][fontcolor="blue"]; struct5 [label= "7"][fontcolor="blue"]; { rank="same"; result -> struct3 -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 2\l"]; LNULL [label="L = NULL"]; i [label="i--"][fontcolor = "red"]; { rank="same"; LNULL -> i } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 1\l"]; result [fontcolor="blue"]; node[shape=box]; struct3 [label= "5"][fontcolor="blue"]; struct4 [label= "4"][fontcolor="blue"]; struct5 [label= "7"][fontcolor="blue"]; { rank="same"; result -> struct4 -> struct3 -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 0\l"]; pivot left right node[shape=box]; struct1 [label= "1"]; struct2 [label= "3"]; struct4 [label= "2"]; { rank="same"; pivot -> struct4 } { rank="same"; left -> struct1 } { rank="same"; right -> struct2 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 2\l"]; result [fontcolor="blue"]; node[shape=box]; struct2 [label= "3"][fontcolor="blue"]; struct3 [label= "5"][fontcolor="blue"]; struct4 [label= "4"][fontcolor="blue"]; struct5 [label= "7"][fontcolor="blue"]; { rank="same"; result -> struct2 -> struct4 -> struct3 -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 1\l"]; result [fontcolor="blue"]; node[shape=box]; struct1 [label= "2"][fontcolor="blue"]; struct2 [label= "3"][fontcolor="blue"]; struct3 [label= "5"][fontcolor="blue"]; struct4 [label= "4"][fontcolor="blue"]; struct5 [label= "7"][fontcolor="blue"]; { rank="same"; result -> struct1 -> struct2 -> struct4 -> struct3 -> struct5 } } ``` ```graphviz digraph structs { node[shape=plaintext]; iter [label = "i = 0\l"]; result [fontcolor="blue"]; node[shape=box]; struct0 [label= "1"][fontcolor="blue"]; struct1 [label= "2"][fontcolor="blue"]; struct2 [label= "3"][fontcolor="blue"]; struct3 [label= "5"][fontcolor="blue"]; struct4 [label= "4"][fontcolor="blue"]; struct5 [label= "7"][fontcolor="blue"]; { rank="same"; result -> struct0 -> struct1 -> struct2 -> struct4 -> struct3 -> struct5 } } ``` #### 使用 Linux 核心風格的 List API 改寫上述程式碼 ### 測驗 `2` ## 第 2 週測驗題 [2024q1 第 2 週測驗題](https://hackmd.io/@sysprog/linux2024-quiz2) ### 測驗 `1` 這裡最重要的實作是使用 hash table 來實現在 inorder 裡尋找對應元素的過程。 在 `find` 裡有以下實作 ```c int hash = (num < 0 ? -num : num) % size; hlist_for_each (p, &heads[hash]) { struct order_node *on = container_of(p, struct order_node, node); if (num == on->val) return on->idx; } ``` 透過 `hlist_for_each` 走訪 hash table 上的 linked list,如此比起直接走訪整個 inorder 的元素來得更有效率。 接著 `dfs` 透過遞迴的方式將左節點與右節點依序接上,如下圖所示 ```graphviz digraph BST { node []; root1 [ label = "3" ]; left1 [ label = "9" ]; right1 [ label = "20,15,7" ]; root1 -> { left1 right1 }; l3 [ label = "3" ]; l4 [ label = "9" ]; l5 [ label = "20" ]; l6 [ label = "7" ]; l7 [ label = "15" ]; l3 -> { l4 l5 }; l5->{ l6 l7}; } ``` ### 測驗 `2` ### 測驗 `3`