contributed by <jimmy-liu1021>
kevinshieh0225
&node->list
來取得 dereference list of address. 因為在運算次序中 derefence ->
高於 &
。這樣不必使用 // cppcheck-suppress memleak
list_for_each
, list_for_each_entry
, list_for_each_safe
, list_for_each_entry_safe
q_remove_head
重複做了 list_del(head->next);
可再簡化。作業要求 (詳閱連結內容)
Create a empty queue.
Return NULL if could not allocate space.
malloc()
分配記憶體位置,並由 new
指標指向。如果空間分配失敗,則 malloc
會回傳 NULL
,此時函式回傳NULL
list.h
中的 INIT_LIST_HEAD
初始化INIT_LIST_HEAD
的功能為將 linked list 的 next
及 prev
指向本身
Free all storage used by queue
head
是否為空,若為空則直接return
結束函式container_of
取出節點的記憶體位置,並逐一釋放空間。head
的記憶體空間參考 Linux 核心原始程式碼巨集: container_of,得知 container_of
可以用來得到包含 ptr
之 object
的起始記憶體位址
Attempt to insert element at head of queue.
Return true if successful.
Return false if q is NULL or could not allocate space.
Argument s points to the string to be stored.
The function must explicitly allocate space and copy the string into it.
流程
1.如果 head
為 NULL
則 return false
2.使用 malloc()
分配 emelent_t
大小的記憶體空間,若失敗則 return false
3.使用 strlen()
取得字串長度,並分配複製字串所需的空間
分配時要多一個位元組存放 NULL pointer
4.使用 list.h
中的函式 list_add()
將節點加在 head
之後
list_add()
的功能為,將 node
接在 head
之後,並把 link 接好
Attempt to insert element at tail of queue.
Return true if successful.
Return false if q is NULL or could not allocate space.
Argument s points to the string to be stored.
The function must explicitly allocate space and copy the string into it.
q_insert_tail()
與 q_insert_head()
幾乎相同,區別只有加入節點時使用的是 list_add_tail()
Attempt to remove element from head of queue.
Return target element.
Return NULL if queue is NULL or empty.
If sp is non-NULL and an element is removed, copy the removed string to *sp
(up to a maximum of bufsize-1 characters, plus a null terminator.)
NOTE: "remove" is different from "delete"
The space used by the list element and the string should not be freed.
The only thing "remove" need to do is unlink it.
REF: https://english.stackexchange.com/questions/52508/difference-between-delete-and-remove
head
是否為 NULL
及 queue 是否為空,若成立則回傳 NULL
value
,所以用 container_of
取出第一個節點的位址,並使用 memcpy
將其所存的字串複製下來,複製的大小根據 bufsize
Attempt to remove element from tail of queue.
Other attribute is as same as q_remove_head.
q_remove_head
相似,不同處為取出的點為 head->prev
即最後一個節點Return number of elements in queue.
Return 0 if q is NULL or empty
list.h
中的巨集函式 list_for_each()
走訪每個節點,以計算linked list的長度Delete the middle node in list.
The middle node of a linked list of size n is the
⌊n / 2⌋th node from the start using 0-based indexing.
If there're six element, the third member should be return.
Return true if successful.
Return false if list is NULL or empty.
此案例中,快指標每一次往前進兩個節點,而慢指標每一次往前進一個節點。如此一來,當快指標指向最後一個節點時,慢指標恰好指向中間的節點
Delete all nodes that have duplicate string,
leaving only distinct strings from the original list.
Return true if successful.
Return false if list is NULL.
Note: this function always be called after sorting, in other words,
list is guaranteed to be sorted in ascending order.
dup_flag
去記錄刪去這個行為是否有被執行,若有 (表示有與首個節點重複的點) 則將首個節點也刪去
實作時原本以為只需要刪去重複的多餘字串 (留下1個,e.g. 112233 留下123) 即可,但在 make test
時失敗,才發現要刪去所有重複的(e.g. 11223345 只留下 45),使用了flag
的方式去紀錄,但是造成程式碼大量重複
Attempt to swap every two adjacent nodes.
ptr
指標指向head
,將 tmp
指標指向third
Step2. second
的 next
指向 first
Step3. head
的 next
指向 second
Step4. first
的 next
指向 third
,以上步驟將 next
皆布置完畢
Step5. 將各個節點的 prev
接好,並將 ptr
指向 third
準備進行下一個循環
Reverse elements in queue
No effect if q is NULL or empty
This function should not allocate or free any list elements
(e.g., by calling q_insert_head, q_insert_tail, or q_remove_head).
It should rearrange the existing ones.
Sort elements of queue in ascending order
No effect if q is NULL or empty. In addition, if q has only one element, do nothing.