contributed by < v0103
>
Vincent550102
vax-r
q_sort
、q_ascend
、q_descend
、q_merge
尚未實作q_reverseK
可善用 list_cut_position
、list_splice_init
等內建巨集,例如:w96086123
q_insert_head
中有提出必須檢查的條件,這時的排版應該要以編號來表示而不是直接使用換行來表達,這樣會讓人不知道這裡是在表達什麼意思。vestata
無論標題和內文中,中文和英文字元之間要有空白字元 (對排版和文字搜尋有利)
q_new
這裡的 if
條件是為了確保前面的 malloc
函式能夠成功配置足夠大小的記憶體給 new
指標。若配置失敗, malloc
會返回 NULL
,因此在這種情況下,函式會直接回傳 NULL
。
初始化部分原本是以手動方式實作,後來發現在list.h
中已經有適用的函式,因此決定直接使用該函式。這樣的做法有助於提高程式碼的重用性和可讀性,避免重複造輪子。
閱讀 Wikipedia: Reinventing the wheel,思考前後文是否合理。
q_free
不知道就說不知道,不要說「不太知道」,工程人員說話要精準。
這題我也想使用 list.h
裡的函式或巨集,但是不太知道 怎麼使用,因此參考 alanjian85。
因此這裡使用 list.h
的巨集 list_for_each_entry_safe
,走訪整個佇列,用 safe
來指向 entry->next
,不使用 list_for_each_entry
是因為執行 q_release_element
會將entry刪掉以致於執行 entry->next
會出錯,整個佇列會遺失,至於 list_for_each_entry
的參數list則是要看 queue.h
裡的 element_t
結構的命名。另外如果佇列是 NULL,則會在一開始就結束該函式。
q_insert_head
避免非必要的項目縮排 (即 *
),以清晰、明確,且流暢的漢語書寫。
這裡有個要檢查的點
輸入的 list 是否為 NULL
malloc
new
有沒有成功
strdup
函式本身會呼叫 malloc
因此也需要檢查是否成功
都沒問題才能將該 new
插入到 list
裡。
q_insert_tail
和上述 q_insert_head
相似,僅需將 list_add
改成 list_add_tail
即可完成。
q_remove_head
作業說明有提到,remove
和 delete
的差別,remove
不會將節點抹除,因此這裡只有使用 list_del
來 unlink,沒有使用 free
來釋放該節點的記憶體。兩個要注意的點是
empty
strncpy
後 sp
有 null character 。q_remove_tail
和上述 q_remove_head
相似,僅需將 list_first_entry
改成 list_last_entry
即可完成。
q_delete_mid
這裡我使用快慢指標,fast
每次走 2 步,slow
每次走 1 步,當 fast
走訪完整個 list,slow
則會在鏈結串列的中間。
我嘗試幾次後發現有兩個要注意的點
fast
和 slow
一開始要從 head->next
出發才是正確的fast
指到 head
或 head->prev
都算是走訪完 list找完中點後,由於 delete 是要將該節點記憶體釋放,所以除了用 list_del
unlink 要再使用 q_release_element
釋放整個 element 的記憶體。
改進漢語表達。
針對環狀雙向佇列,提出更快的方法。
TO DO : 針對環狀雙向佇列可以使用兩個指標,一個往next,一個往prev
q_delete_dup
這段程式碼的目標是移除重複項目。程式使用 list_for_each_entry_safe
來走訪整個 list
,並使用 strcmp
函數比較項目的值。如果發現重複的項目,它將刪除所有重複的項目,但保留最後一個。為了將最後一項也刪掉,我使用 dup_last
變數,來確保最後一個重複的項目會被刪除。
q_swap
由於 swap 只需要改變每個 element 的鏈結串列,不需要值 不需要改變節點當中的數值,所以我這裡使用的是 list_for_each_safe
,再使用 list_del
和 list_add
就可以將兩者 swap (下方解釋),最後 safe = node->next
可以確保都是兩個為一組 swap。
後來看到 list_move
這個函式,剛好就是 list_del
和 list_add
的組合,在 list.h
裡可以看到他的敘述是 Move a list node to the beginning of the list
不過將輸入更改後便可以達到我要的功能 將節點 node 移至節點 safe 後
。
q_reverse
reverse 跟 swap 一樣都只需要更改鏈結串列的指向,我一樣使用 list_for_each_safe
走訪每個節點,並將他們都Move a list node to the beginning of the list
,這次是使用他真正的功能了,如此一來整個鏈結串列就被 reverse 了。
q_reverseK
我這裡使用最土炮的方法,在 q_reverse
的基礎上加上兩個計數器,count_turn
用來確認後面是否還有完整的 k 組 element,count_k
則是用來數已被 reverse 的節點數,若達到 k 個則將重新計數,並改變後面節點要插入的位置。
I-HSIN Cheng
這裡是開發筆記不是教學頁面,不需要闡述每個函式的邏輯與做法,程式碼本身應該清楚到不需文字解釋即可理解,除非有任何特別之處,應該寫出可改進之處,另外說明文字的贅字太多且解說不清晰。