contributed by < csm1735
>
queue.c
釋放已配置的記憶體,考量到刪除節點後,還需要找到下一個節點的位置,因此這邊選擇使用 list_for_each_entry_safe
來實作。
實作後發現 q_insert_head
跟 q_insert_tail
在程式碼上有大量重複的狀況,考量到精簡度及維護性,因此選擇將重複部分獨立成 new_element
來使用。
q_insert_head
跟 q_insert_tail
主要差異在於一個使用了 list_add
而另一個使用了 list_add_tail
。
一開始沒有看懂說明,以為要對 sp
做 malloc
,所以產生了問題,後來發現應該直接去檢查 sp
是否為 NULL
, 再來做 strncpy
。
跟 q_remove_head
主要差異在於其使用了 list_first_entry
而這邊使用了 list_last_entry
。
目前沒有想到其他更有效率的做法,只能透過走訪所有的節點來計算 size
。
找出中間的節點後,將其移除並釋放記憶體。
這邊函式需要佇列在排序完的狀況下執行,去刪除具有相同字串的節點,假設這邊有 個相同字串的節點,那麼前 個可以透過 strcmp
的判斷來做刪除,第 個則是透過 flag
的檢查來做刪除 。
撰寫更精簡的程式碼。
將 list_for_each_entry_safe
內調整為更精簡的寫法
此函式 swap
的實質意義就等同於 q_reverseK
在參數 k 值為 2 的時候。
是否可據此進一步精簡程式碼?
將所有的節點依序搬到頭後就等同於完成 reverse
, 要注意這邊得使用 list_for_each_safe
。
這邊參考了 komark06 的作法,每 k 個節點就切出來做 reverse
的動作,然後再將其連接回去。
不用張貼完整程式碼,你應該闡述自己的想法、考量因素,還有分析已有方案的優缺點,並記錄過程中遇到的問題。
mergeTwoList
原先的遞迴寫法,雖然程式碼較為精簡,但在 make test
時效能上無法通過,因此修正為以下的迴圈版本
以上 merge sort
實作參考自 Linked List Sort
透過 merge sort
來完成排序,在實作時一開始忘記將最後一個節點的 next 指向 NULL ,導致程式有無窮迴圈的問題,需要注意,另外在排序完後,記得要將每個節點的 prev 重新連結上,還有將最後一個節點的 next 重新指向 head ,這樣才算完成。
這邊的做法是從後往前掃來做檢查, maxNode
即為當前節點右側的節點中擁有最大值的那一個,當前節點的值如果小於 maxNode
的值則做刪除的動作,反之則更新成 maxNode
。
這邊很直接的先將所有的佇列連接在一起,然後再一口氣一次將全部做排序,但這邊並沒有運用到各個佇列已經排序好的性質,可以再思考更好的做法。
避免不精準的詞彙,「一口氣」對應的英語是什麼?這對於解析程式有何幫助?
已修正,謝謝老師
目前測試分數 95 / 100
複雜度仍須提升
用 make valgrind
來測試,發現大部分都有如下的狀況:
後來發現在 qtest.c
中的 q_quit
裡面,第一行就直接做了 return true;
,因此趕快將這行拿掉就恢復正常了,而後來發現這個問題在原本的 lab0 已經被修正掉了,這也提醒了我要記得同步專案。
測試結果 100 / 100
一開始花了一些時間摸索如何在 qtest
中提供新的命令,後來發現要在 qtest.c 中的 console_init
加入以下程式碼。
並在 qtest.c 中新增 do_shuffle
函式來實作洗牌功能。
以下 q_shuffle
則是基於 Fisher–Yates shuffle 演算法的 Modern method 來實作。
如果隨機抽選到的 node
是尚未被選擇的最後一個 node
(也就是將被交換的那一個),則省略交換的過程,直接做 continue ,反之則針對值來做交換的動作。
有待分析
option entropy 1