contributed by < yan112388
>
基本結構:考慮 struct __node 為節點結構,有一個 int 儲存資料,及一個 left pointer, right pointer 和 next pointer
本題實作了一個非遞迴 (non-recursive iterative) 的快速排序演算法,其中:
在 quicksort
中,可見以下程式碼初始化 begin 和 end。
由此可知 list_tail
如其名,目的為找到鏈結串列的尾端節點
AAAA 應填入 (*left)->next
,使 left持續往下個節點走訪,直到最後一個節點為止
BBBB 應填入 (*left)->next
,與前者作用相似,直到無節點為止
本題quicksort原理
CCCC 應填入 p->next
,用來拜訪區段內的每個節點
DDDD 填入 list_tail(&left)
,取得 left 的尾節點
EEEE 填入 list_tail(&right)
,取得 right 的尾節點
改進方案
max_level
不須開到 2*n
? n
即可Timsort:
該排序法考量現實世界中的資料大多為已排序的,首先將序列分成多個 runs,使用插入排序法做排序,再以合併排序法將 runs 合併,最後排序完成。
find_run()
:找到每個 run ,如果該 run 為降序排列,則反轉為升序
merge_force_collapse()
:強制合併剩餘的 runs ,直到剩餘 runs 的數量小於 3 個,過程中呼叫 merge_at()
merge_collapse()
:根據剩餘的 runs 數量決定要合併哪兩個 runs,過程中呼叫 merge_at()
merge_at()
:合併位於 at 處的兩個相鄰 runs
merge_final()
:將最後兩個 runs 合併,並呼叫 build_prev_link()
build_prev_link()
:將單向鏈結串列轉換為雙向循環鏈結串列
以 Linux 核心的 hash table 架構實作 LeetCode 105 Construct Binary Tree from Preorder and Inorder Traversal
其中,next 指向相鄰的節點本身,而 pprev 宣告為指標的指標,指向指著自身節點的指標。
Q:為甚麼要使用 hash table?
建構過程,需要根據前序,在中序中找到對應的索引來確定左右子樹的範圍。直接在中序內線性查找的時間複雜度為 O(n) ,對於大規模的數據會很費時。因此,使用 hash table 能加快尋找速度。
find
:計算 hash 值,在中序中查找指定元素的索引
node_add
:將新的節點加到 hash table 中,使用 Division method 作為 hash function
dfs
:
idx
idx
將中序分成左子樹和右子樹參考資料:Linux 核心的 hash table 實作、内核基础设施——hlist_head/hlist_node结构解析
測試程式
根據給予的前序和中序,建構出一顆根為 root 的二元樹
以下兩個函式能根據傳入的根結點,印出二元樹的前序與中序
實作一個 LRU Cache
lRUCacheCreate
: 建立一個新的 LRU Cache,指定其容量大小為 capacity
lRUCacheFree
: 釋放 LRU Cache 所佔用的記憶體空間
lRUCacheGet
: 從快取中獲取特定 key 對應的值,如果該值存在,則將該節點移動到鏈結串列的頭部
lRUCachePut
: 將指定值依據 key 放進 Cache,如果 Cache 已滿,則移除最久未被存取的節點。如果 key 已存在,則更新其值並將該節點移動到鏈結串列的頭部
在指定的記憶體空間找出第 N 個設定的位元
find_nth_bit
*addr
:指向要查找的記憶體區域起始位置的指標size
:要查找的記憶體區域的位元大小n
:要查找的是第幾個設定的位元(從 0 開始數)如果 n
大於或等於 size
,則直接回傳 size
,因為 n
已經超出了給定的範圍
如果 size
是一個很小的常數值且小於等於 BITS_PER_LONG(64)
並大於0,則只需檢查第一個 unsigned long
值
如果以上皆非,則利用巨集 FIND_NTH_BIT
GENMASK
:依據給定的範圍,產生連續的 bitmask
h
和 l
是需要設置為 1 的最高有效位和最低有效位的位置GENMASK(5, 0)
會生成 00000000000000000000000000111111(二進位)FIND_NTH_BIT
:逐一檢查每個 unsigned long
值中設定的位元數量。如果設定的位元數量大於 n
,則進入 found
標籤,使用 fns
函數在該值中找到第 n
個設定的位元。
__ffs
:回傳該數值中最右邊值為1的位元的位置
延伸問題皆待補充