contributed by < Welly0902 >
本作業參考 zeddyuu 同學及 paul90317 同學
注意書寫規範:中英文間用一個半形空白字元區隔。
:notes: jserv
make test
取得 100 分lib/list_sort.c
並將其加入專案中shuffle
使用 WSL2 Ubuntu 22.04
/tools/perf
make 起來,過程如下:修改 kernel.perf_event_paranoid
的方式:
在 /etc/sysctl.conf
中加入 kernel.perf_event_paranoid = -1
修改完成後 sudo sysctl -p
即修改完成
Perf 測試使用:
Q: 如何實際檢驗所寫 function 對 queue 的運行狀況?
A: 修改完程式後執行 make
再運用 ./qtest
去模擬各個 function 的運行狀態
目標: 利用 list.h 中定義好的 API
Q: 為何 romove element 需要 return element_t 型態的 pointer?
strncpy: 將 source 的前 num 個字元從 source 複製到 destination。
char * strncpy ( char * destination, const char * source, size_t num );
需注意要預留 null terminator \0
的位置。
list_first_entry
換成 list_first_entry
即可找到 tail
list_for_each_entry_safe
delete 後需要break
根據 list.h 註解,list_for_each_entry_safe(entry, safe, head, member)
中的 safe
參數為當前節點的下一個節點,先記錄下一個節點的位置以避免在刪除節點時發生錯誤。
運用 flag
去紀錄是否重複,以刪除最後一個重複節點。
運用 list_move(node, head)
,可以用 list_move(node, node->next)
來達到交換節點的效果。 list_move
會進行兩個動作: list_del
及 list_add
,以下面是意圖來呈現如何交換:
此處再以graphviz改進
list_add
的部分在 list.h
中為:
因此 list_add(node, node->next)
為:
由上過程可見,兩個 node 前後 swap了,程式碼為下:
用 list_for_each_safe
走訪每個節點,走訪該節點時從 list 中刪除再加到 head 下一個即可達到 list reverse 的效果。
考量第一個 iteration 不會對 list 造成任何變動,加一個變數 flag 來跳過第一個 iteration。
此為每 k 個元素做一次 reverse。可利用上一個 q_reverse
每走過k個元素用 list_cut_position
拆分成剩餘 list 中前方 k 個要 reverse 的,以及後方剩餘還沒做的。再將切出來的前 k 個 cut 用 q_reverse
做 reverse。最後再以 list_splice_init
接到目前 tmp_head
的前方。達成 reverse 的效果。
merge
的部分取兩 list 的節點出來比大小:
再來將 input linked list 切分為二後,用前面寫好的 q_sort
排好,再進行 merge:
Q: merge
function 中初始為何是l1->next,而不是l1?
此實作若節點右側有值比他大,則當下點刪除。思路可利用 doubly linked list 雙向的特性,從又往左走訪各節點。以一個變數記錄當下最大,小於即刪除來達到相同效果。
此實作的 input 為一個 linked list,每個節點連著一個 queue。故透過 while 迴圈每次合成 floor((q_count + 1) / 2)
個 queue。