# 2020q3 Homework1 (lab0) contributed by < `fdfdd12345628` > ## 作業要求 參閱[此處](https://hackmd.io/@sysprog/2020-lab0#-%E9%A0%90%E6%9C%9F%E7%9B%AE%E6%A8%99) * q_new: 建立新的「空」佇列 * q_free: 釋放佇列所佔用的記憶體 * q_insert_head: 在佇列開頭 (head) 加入 (insert) 給定的新元素 (以 LIFO 準則) * q_insert_tail: 在佇列尾端 (tail) 加入 (insert) 給定的新元素 (以 FIFO 準則) * q_remove_head: 在佇列開頭 (head) 移除 (remove) 給定的元素。 * q_size: 計算佇列中的元素數量。 * q_reverse: 以反向順序重新排列鏈結串列,該函式不該配置或釋放任何鏈結串列元素,換言之,它只能重排已經存在的元素 * q_sort: 「進階電腦系統理論與實作」課程所新增,以遞增順序來排序鏈結串列的元素,可參閱 Linked List Sort 得知實作手法 ## 實作過程 由於 `q_insert_tail` 與 `q_size`都需要 $O(1)$ 時間,因此在 `queue.h` 修改如下 ```clike= typedef struct { list_ele_t *head; int size; list_ele_t *tail; } queue_t; ``` 依序實作每個功能後,發現test case有些是測試空queue或是在q=NULL的情況,因此在每個function都會判斷指標是否為`NULL`,如下 ```clike= if (q == NULL) { return false; } ``` 藉此來增加程式的穩定性 由於在insert node時,需要同時判斷head與tail是不是指向正確的node,因此兩邊都針對size為零時,有特別的處理方式 ```clike= if (q->size == 0) { q->head = newh; q->tail = newh; } ``` 並且在remove node時,也會判斷是不是最後一個節點 ```clike= // temp is q->head if (temp == q->tail) { q->tail = NULL; } ``` 並且在最後修正了不少dereferencing null pointer,加入了很多情況的判斷 這份作業大概花費了8小時(沒有很認真記錄,僅參考) ## massif-visualizer 下圖為執行`make valgrind`後,visualizer的圖型 ![](https://i.imgur.com/HFfOPgN.png) 下圖為執行`trace-02-ops.cmd`後,visualizer的圖型(考慮到此test case執行操作簡單,可以很清楚的看到不同操作造成的影響) ![](https://i.imgur.com/04hUFKx.png) 可以看到remove head會突然增加記憶體用量,可能是測試程式所吃掉的,很快就會釋放回來。