contributed by < w96086123
>
left
代表比 value 小的集合。
right
代表比 value 大的集合。
next
表示此 node 的下一個 node 。
value
表示此 node 的數值。
將一個 node_t 加入至 list 的 head 。
尋找此 node_t 中 left 的最後一個 node_t ,並且回傳該指標。
其中的 AAAA
為 (*left)->next。
尋找此 node_t 中 left 的長度。
其中的 BBBB
為 (*left)->next。
建立一個 value 為 n 的 node_t ,並且將 node_t 加入至 list 的頭,且回傳該指標。
將 list 中的已配置記憶體的全部釋放。
檢查此 list 是否已完成排序。
將 array 中的資料已亂數交換的方式打亂。
此方法利用堆疊取代原本的遞迴呼叫。
此區主要作為切割並且儲存的區域,因此我將此區分成三個區域了解。
藉由上面解析,可以知道每次的切割會新增兩個區塊,因此最大堆疊的空間需要 2 * n 。
此區將 list 中進行分類。
逐一利用 list_add
進行分類,分類條件為 n->value > value
,若為真,則表示較大,將 n 分類為 right,否則,將 n 分類為 left 。
因此 CCCC
為 p->next 。
原本的狀態
進行分類過後的狀態
建立一個長度為 100000 的 array ,順序則為 1 至 100000,並且利用 shuffle
進行打亂,後建立打亂後順序的 list ,並進行 quick_sort
排序,排序後利用 list_is_ordered
進行排序結果的判斷,最後利用 list_free
將記憶體釋放,並且釋放該 array 。
因為每次的切割都需要使用兩次 list_tail
,但每次使用都需要 O(N) ,如果改成使用雙向鏈結串列的方式實做,時間複雜度將降低為 O(1) 。
新增 prev
節點。
藉由新的結構,可以直接訪問最後的節點,無須逐步訪問,因此時間複雜度可變為 O(1) 。
由於修改為新的結構,因此在建立的過程中也需要做相對應的修改。
單向鏈結 | 雙向鏈結 | |
---|---|---|
處理時間 (s) | 0.049148 | 0.036808 |
由上表可知,這樣得修改方式是有提昇處理時間。
若想要避免最壞狀況,可以使用 Median of Three 的方式取得 pivot ,這樣可以避免一直取得最大或是最小值。
先尋找 run
由左到右尋找非嚴格遞增或遞減的序列,每個 run 的長度盡量符合 minrun 跟 2 的冪。
內部 run 進行插入排序法
利用合併排序的方式進行合併
利用深度優先搜尋的方式建立樹。
此函數主要作用為將 n 插入至 h 的頭。
因此 AAAA
為 h->first 。
此函數為尋找特定值。
BBBB
這裡要遍歷 hlist_node ,因此 BBBB
為 &heads 。
每次的遍歷都需要將當前指針轉換為 order_node,因此 CCCC
為 list_entry 。
此函數主要將創立一個新的 order_node ,並且將此 node 放入置 hlist_head。
因此 DDDD
為 heads 。
利用深度優先搜尋法的方式建立 Tree。
先利用 find
尋找出 preoder[pre_low]
在 inorder 中的索引值,此索引值稱為 idx
。
切割方式:
左子樹:
preorder : pre_low + 1 至 pre_low + (idx - in_low) 。
(idx - in_low) 表示有多少個節點。
inorder : in_low 至 idx - 1 。
右子樹:
preorder : pre_high - (in_high - idx - 1) 至 pre_high 。
(in_high - idx - 1) 表示有多少個節點。
inorder : idx + 1 至 in_high 。
循環利用上面的方式,就可以將有 preorder 與 inorder 的序列,轉換為 Tree 了。
capacity
用於儲存 LRU 緩存的容量。
count
用於紀錄當前 LRU 緩存中儲存的數量。
dhead
用於紀錄 LRU 中節點的訪問順序,用於尋找替換順序。
hhead
用於紀錄 LRU 中節點的哈希表連結。
key
節點的鍵值。
value
節點的值。
node
與其他節點的指標。
link
用於與 LRU 的連結。