contributed<
brian049
>
1
Optimized QuickSort — C Implementation (Non-Recursive)
list_tail 函式藉由 while 迴圈迭代來找到 list 的尾端。
欲求 list 的長度時,使用 while 迴圈迭代並計數來得到長度。
以下程式碼為實作 Quicksort 的主要部分。
主要程式碼當中,一開始設定 pivot
為最左邊的節點,p
為 pivot
的下一個節點。再來判斷除了 pivot
以外的節點是否大於或是小於 pivot
的值,若是大於 pivot
則將該節點加到 right
序列當中,若是小於則加到 left
序列當中。
切割序列之後將整體序列分成三部分,第一部分首尾節點分別是 left
以及 list_tail(&left)
,第二部分為 pivot
單一節點,第三部分則是 right
以及 list_tail(&right)
。
2
Timsort
在測驗 2 當中有指出 Timsort 與 merge sort 最大的差異在於「定義一個 minrun (最小運行長度),用以表示每個 run 的最小長度,若長度太短,就用二分插入排序,將 run 後面的元素插入到前面的 run 裡面。」以及合併時採取 Galloping mode,進而降低 cache miss、降低記憶體開銷、降低比較次數。
以下程式碼為 timsort merge 的實作,用 tail
指標指向 head
來達到首尾相接的鏈結串列,若是 a 指向的節點的值小於或等於 b 節點的值,則將 a 指向的節點加到事先宣告的佇列當中,反之則將 b 指向的節點加入佇列,直到 a 或 b 佇列為空。
以下程式碼將 list
佇列接到 tail
後面,並在最後將尾端與 head
相接,形成首尾相接的佇列。
以下程式碼是主要實作 timsort 的部份。逐一解說,先將環狀佇拆開成單向鏈結,在藉由 find_run
函式來切割出 run,再使用 merge_collapse
函式來對 run 進行檢查並整理,以確保堆疊中的 run 符合 timsort 的性質。
接下來使用 merge_force_collapse
函式對堆疊進行整理,再進行合併並重新接回雙向環狀鏈結。
1
Construct Binary Tree from Preorder and Inorder Traversal
hlist_add_head
函式新增節點至鏈結的頭部並更新 h
指標。
以下程式碼藉由雜湊值來查找想要找的數值 num
,利用 hlist_for_each
函式來比對,若找到則回傳當前的索引值 idx
,沒有找到則回傳 -1。
node_add
函式計算節計算雜湊值,再使用 hlist_add_head
來新增節點至對應雜湊的 heads
位置。
2
LRU cache
hlist_del
函式將欲刪除之節點的前一個節點的指標指向欲刪除節點的下一個節點,來達到刪除節點的功能,而若是下一個節點存在,則更新該節點指向前一個節點的指標。
lRUCacheFree
函式利用 list_for_each_safe
來遍歷所有節點,並釋放節點所佔用的記憶體。
lRUCacheGet
函式作用是在 LRUCache 中找尋指定值,若是找到則將 cache->link
放到最前面也就代表最近有被使用到。
lRUCachePut
函式分成兩部份,上半部找尋欲加入的 key
值是否存在於雜湊表當中,如果存在則將其移動到最前端來表示最近使用過,類似於 lRUCacheGet
函式的操作方式。
未存在於雜湊表時,也就是函式中的下半部,先檢查現有數量是否相等於 capacity
,相等則代表快取已滿,此狀況就會刪除最少使用的數據,也就是最後一個節點,刪除後再新增新的 key
以及其 value
進快取。除此之外,若是快取未滿,就會將新的 key
以及其 value
加入到快取當中,並使當前數量 obj->count
加一。
3
find_nth_bit
ffs 目的是要找到第一個 set 的 bit。在定義中不斷使用 AND 操作來找第一個 1 的 bit 的位置。
__clear_bit
函式主要用於 fns
函式當中,目的是為了在找到第一個 set 的 bit 的時候,能夠透過清除 bitmap 中的指定 bit,並重複使用 fns
函式來找到第 n 個 set 的位置。
bit index 可以透過 BIT_WORD
巨集來獲得,再搭配 addr
記憶體空間,可得出指定 bit 的位元組。且運用 BIT_MASK
巨集得到 mask 用於清除指定 bit。
FIND_NTH_BIT
把原本的資料以每 64 bit 為單位去作裁切,計算每段其中被設置的位元數量,若位元數量大於要找的位元數 n
,就代表目標位元就在該段內,直接返回。反之則將 n
減去位元數並進行下一個迴圈。