contributed by <love1357983
>
linux2020
為了讓 q_insert_tail
和 q_size
在 的時間複雜度,
在 queue_t
結構中增加以下欄位。
tail
變數名稱 - list_ele_t
型態size
變數名稱 - int
型態queue.h
實作:在執行 qtest
程式一開始,會先呼叫 queue.h
中 q_new
函式,將欄位進行初始化。其中使用 malloc
函式,配置一個 queue_t
需要的空間,如果成功的話會回傳 void*
的記憶體位址;若失敗則回傳 NULL
,所以需要檢查 malloc
是否成功。
將所建立 queue_t
型態的 q
記憶體空間釋放,包含每個節點上的動態配置的資料 value
欄位。在運行前一樣會先檢查 queue_t
是否存在,如果不存在直接返回。在這裡使用 while
迴圈走訪鏈結串列中各個節點。在 while
迴圈中,使用 prev
記錄目前 tmp
的記憶體位置,在 tmp
移動到下一個節點後,再將該節點中的 next
欄位作釋放動作,完成該節點在記憶裡空間完全釋放完畢。
LIFO
插入使用 LIFO
方法進行排序,先建立 newh
的 list_ele_t
節點,將接收到的 s
,使用 strdup
複製字串加入 newh
的 value
中。把 q->head
接續在 newh
的 next
中,修改 q->head
為 newh
,判斷 q_size
是否為 0
,如果為 0
時,再把 q->tail
設定為 newh
,最後再將 q_size
增加 1
。
FIFO
插入同理,使用 FIFO
方法進行排序,先建立 newt
的 list_ele_t
節點,同樣將接收到的 s
,使用 strdup
複製字串加入 newt
的 value
中,把 newt
的 next
設定為 NULL
,把原 q->tail->next
為 NULL
設定為先前建立出的 newt
,再把原先的 q->tail
設定為 newt
進行取代,最後將 q_size
增加 1
。另外,在呼叫此函式開始時,會先取得 q_size
進行判斷,如果為 0
時,會呼叫與 q_insert_head
相同的程式碼,進行新增節點動作。
將取得 q->head->value
節點內容複製到 sp
中,然後釋放該節點及資料所佔用的記憶體空間。先建立 tmp
的 list_ele_t
節點,記錄 q->head
該節點記憶體位置,再將 q->head
指向 tmp->next
記憶體位置,再把 tmp
記憶體位置進行釋放,將 q_size
減 1
。若 q_size
等於 0
時,須將 q->tail
記憶體空間進行清空動作。
如 queue_t
加入記錄佇列的 size
個數,可將計算 linked list 減少所需時間,將時間複雜度從 縮短到 。
此函式限制在不建立額外配置空間下,先建立 prev
初始狀態為 NULL
, curr
初始狀態為 q->head
, prec
初始狀態為 q->head->next
,共三個 list_ele_t
節點。將當前的 curr
佇列位置從新指向 next
的 prev
記憶體位置,因為 curr
的 next
已經從新指向了,所以 prec
節點是為了讀取原有 q->next
佇列中的記憶體位置,使用 while
迴圈進行 queue_t
輪詢至 prec
為 NULL
為止,最後在將 queue_t
中 head
, tail
進行對調動作。
以下程式碼使用 Bubble Sort 法,以遞增順序來排序鏈結串列的元素,其執行的時間複雜度為 。透過 strcasecmp
將 first->value
和 curr->value
比較,當strcasecmp
回傳數值小於 0
時,把兩個節點的 value
交換動作。
list_ele_t
中的 value
內容進行交換的動作,這邊有可能在兩者被分配的記憶體空間大小不同,而造成記憶體洩露 (memory leak),後續會針對樣的問題進行實驗與研究。
// Mar 3 -> make test