# 2019q3 第 4 週測驗題 :::info 目的: 檢驗學員對 linked list 的認知 ::: --- ### 測驗 `1` 考慮一個單向 linked list: ```cpp typedef struct __list { int data; struct __list *next; } list; ``` 在不存在環狀結構的狀況下,以下函式能夠對 linked list 元素從小到大排序: ```cpp list *sort(list *start) { if (!start || !start->next) return start; list *left = start; list *right = left->next; LL0; left = sort(left); right = sort(right); for (list *merge = NULL; left || right; ) { if (!right || (left && left->data < right->data)) { if (!merge) { LL1; } else { LL2; merge = merge->next; } LL3; } else { if (!merge) { LL4; } else { LL5; merge = merge->next; } LL6; } } return start; } ``` 請補完程式碼。 ==作答區== LL0 = ? * `(a)` `left->next = NULL` * `(b)` `right->next = NULL` * `(c)` `left = left->next` * `(d)` `left = right->next` LL1 = ? * `(a)` `start = left` * `(b)` `start = right` * `(c)` `merge = left` * `(d)` `merge = right` * `(e)` `start = merge = left` * `(f)` `start = merge = right` LL2 = ? * `(a)` `merge->next = left` * `(b)` `merge->next = right` LL3 = ? * `(a)` `left = left->next` * `(b)` `right = right->next` * `(c)` `left = right->next` * `(d)` `right = left->next` LL4 = ? * `(a)` `start = left` * `(b)` `start = right` * `(c)` `merge = left` * `(d)` `merge = right` * `(e)` `start = merge = left` * `(f)` `start = merge = right` LL5 = ? * `(a)` `merge->next = left` * `(b)` `merge->next = right` LL6 = ? * `(a)` `left = left->next` * `(b)` `right = right->next` * `(c)` `left = right->next` * `(d)` `right = left->next` :::success 延伸問題: 1. 解釋上述程式運作原理; 2. 指出程式改進空間,特別是考慮到 [Optimizing merge sort](https://en.wikipedia.org/wiki/Merge_sort#Optimizing_merge_sort); 3. 將上述 singly-linked list 擴充為 circular doubly-linked list 並重新實作對應的 `sort`; 4. 依循 Linux 核心 [include/linux/list.h](https://github.com/torvalds/linux/blob/master/include/linux/list.h) 程式碼的方式,改寫上述排序程式; 5. 嘗試將原本遞迴的程式改寫為 iterative 版本; 6. 將 [2019q1 第 3 週測驗題 (下)](https://hackmd.io/@sysprog/SkrVSKiU4) 提及的 XOR linked list 列入考量,也實作對應的排序程式,並比較效能和記憶體開銷; 7. 比照 [List Sort](https://arxiv.org/pdf/1310.7890.pdf) 的手法來分析前述程式 (含擴充版本) 的效能表現; ::: ---