# 2023q1 Homework1 (quiz1) contributed by < `kart81604` > :::danger 注意細節! :notes: jserv ::: ## 測驗一 :::success AAA = `item` BBB = `list` CCC = `list_for_each_entry_safe` DDD = `list_move_tail` EEE = `list_move_tail` FFF = `list_splice_tail` ::: #### 程式碼運作原理 參數介紹 : `pivot` : queue 中第一個元素,拿來做比較。 `list_less` : 小於 pivot 的 `item` 會接上此 queue 。 `list_greater` : 大於等於 pivot 的 `item` 會接上此 queue 。 將 input 的 queue 的第一個 `item` 作為 pivot ,再將比 pivot 小的 `item` 組成新的 `list_less` queue ,其餘的為 `list_greater` queue 。 ```graphviz digraph init{ rankdir = "LR" head[label="head",shape=squre] pivot[label="6",color=red] head->pivot->7->5->9->2 } ``` ```graphviz digraph sort{ rankdir = "LR" greater[label="list_greater", shape=squre] less[label="list_less", shape=squre] less->5->2 greater->7->9 6[color=red] } ``` 再利用遞迴,對這兩個 queue 進行排序,這邊展示排序 `list_less` 。 :::info 這邊的 `list_less'` 跟 `list_greater'` ,與第一輪的不同。 ::: ```graphviz digraph sort{ rankdir="LR" greater[label="list_greater'",shape=squre] less[label="list_less'",shape=squre] pivot[label="5",color=red] less->2 } ``` ```graphviz digraph sort{ rankdir="LR" less[label="list_less",shape=squre] less->2->5 } ``` 排序完成後回到第一輪,再將兩者組合起來。 ```graphviz digraph sort{ rankdir = "LR" greater[label="list_greater", shape=squre] less[label="list_less", shape=squre] less->2->5 greater->7->9 6 } ``` ```graphviz digraph sort{ rankdir="LR" head[shape=squre] head->2->5->6->7->9 } ``` --- ## 測驗二 :::success GGGG = `list_for_each_entry_safe` HHHH = `list_add_tail` IIII = `stack[++top]` JJJJ = `stack[++top]` KKKK = `stack[top--]` ::: ### 程式碼運作原理 參數介紹 : `partition` : 用作對於 `stack` 最上面非空且非單的 queue ,進行分割。 `pivot` : queue中的第一個元素當作比較的依據。 `list_less` : 將 queue 中小於 `pivot` 的插入此 queue 的第一個。 `list_greater` : 將 queue 中大於等於 `pivot` 的插入此 queue 的第一個。 :::warning 下方的列舉 (即 `- ` 開頭的項目) 非必要,使用簡潔且清晰的描述。 :notes: jserv > 好的,已更改 ::: 在進到第一個 `while` 迴圈之前,建立了一個 `list_head` 陣列 `stack` ,再將 input 的 queue 接到 `stack[0]` 上面。(圖僅列舉有連結 queue 的部分,且 queue 是用doubly-linked list 連結,下圖應注意所連結的 queue 的狀態) ```graphviz digraph sta{ rankdir="LR" subgraph cluster_stack{ label="stack" a[label="0",shape=squre] } a->7->5->8->4->9 } ``` 進入 `while` 迴圈,初始化 `partition` ,然後將 `stack` 最上面的 queue 接到 `partition` 後面。 (紅色表示 pivot ) ```graphviz digraph partition{ rankdir="LR" part[label="partition",shape=squre] pivot[label="7",color=red] part->pivot->5->8->4->9 } ``` 如果 `partition` 不為空且不為單,則初始化 `list_less` 跟 `list_greater` ,將 `partition` 所接的 queue 的第一個獨立出來作為 `pivot` ,對 queue 中每個值做比較,比 `pivot` 小的接到 `list_less` , 大於等於就接到 `list_greater` ,然後將剛剛獨立出來的 `pivot` 接到 `list_less` 的 tail ,接著將 `list_greater` 跟 `list_less` 接到 `stack` 上。 ```graphviz digraph sta{ rankdir="LR" subgraph cluster_stack{ label="stack" b[label="1",shape=squre] a[label="0",shape=squre] } pivot[label="7",color=red] a->9->8 b->4->5->pivot } ``` 如果 `partition` 為空或為單,則把 `stack` 最上面的queue,接到 `head` 的後面。 ```graphviz digraph sta{ rankdir="LR" subgraph cluster_stack{ label="stack" stack2[label="2",shape=squre,color=red] stack1[label="1",shape=squre] stack0[label="0",shape=squre] } stack0->9->8 stack1->7->5 stack2->4 } ``` ```graphviz digraph sta{ rankdir="LR" subgraph cluster_stack{ label="stack" stack2[label="2",shape=squre,color=red] stack1[label="1",shape=squre] stack0[label="0",shape=squre] } stack0->9->8 stack1->7->5 head[label="head",shape=squre] head->4 } ``` --- ## 測驗三 ::: success LLLL = `(uintptr_t)(a) ^ (uintptr_t)(b)` MMMM = `&list->tail` 或 `node` PPPP = `real_next->cmp` ::: ### 程式碼運作原理 藉由 `xorlist_for_each` 的程式碼,其中的參數 `rp` 代表目前所指的點, `node` 指的是 `rp` 的下一個點, `rn` 指的是 `node` 的下一個點,也就是 `rp` 的下下一個點, `rn `藉由 `address_of(rp, node->cmp)` 來得到`node` 下一個點的記憶體地址。