第六章:內核數據結構
阿新 • • 發佈:2019-03-22
模型 帶來 函數 生產者-消費者模型 散列 lin 時間復雜度 條件 搜索 6.1鏈表
鏈表表示一種存放和操作的可變數據元素的數據結構。
鏈表與靜態數組不同的是它包含的元素是動態創建並且插入鏈表的,在編譯時不必知道具體需要多少個元素。
另外鏈表中每個元素的創建時間各不相同,所以它們在內存中無需占用連續的空間。
鏈表中每個元素都包含指向下一元素的指針,當有新元素加入鏈表時,可以簡單的調整指向下一節點的指針就可以了。
6.1.2環形鏈表
通常鏈表中最後一個元素不在指向下一個元素,所以鏈表結尾元素的下一指針為NULL,以此表示它是鏈表的最後一個元素。
但是有些鏈表中,末尾元素並不指向特殊值,相反,它指回鏈表的首元素,這種收尾相連的鏈表叫環形鏈表。
因為環形鏈表提供了最大的靈活性,所以Linux內核的標準鏈表是環形鏈表。
6.2隊列
任何操作系統內核中都少不了一種編程模型:生產者和消費者。該模型可以使用隊列來時實現。
消費者獲得數據的順序與生產者推入隊列的順序一致。
隊列時FIFO,先進先出。
Linux內核通用隊列實現稱為Kfifo。Kfifo對象維護了兩個偏移量:入口偏移和出口偏移。入口偏移時指向下一次入隊的位置。出口偏移是指向下一次出隊的位置。
6.3映射
一個映射,也常稱為關聯數組,其實是一個由唯一鍵組成的集合,而每個鍵必然關聯一個特定的值,映射至少包含三個操作:add、remove、Look。
雖然散列表時一種映射,但並非所有的映射都需要通過散列表實現。除了散列表外,映射也可以通過自平衡二叉搜索樹存儲數據。
通過散列表實現的映射可以提供更好的平均的漸進復雜度。
二叉搜索樹可以在最壞的情況下有更好的表現。
二叉搜索樹滿足順序保障,這將給用戶的按序遍歷帶來很好的性能。
二叉搜索樹最後一個優勢是它不需要散列函數,需要的鍵類型只要可以定義<=操作算子便可以。
6.4二叉樹
樹是一種能提供分層的樹型結構的特定數據結構。
一個二叉樹是每個節點最多只有兩個出邊的樹。
一個二叉搜索樹是一個節點有序的二叉樹,其順序通常遵守以下規則:
根的左分支節點值都小於根節點值
右分支節點值都大於根節點值
所有的子樹也都是二叉搜索樹。
根據以上規則,在樹種搜索一個指定值或者按順序遍歷樹相當快。
一個平衡二叉搜索樹是一個所有節點深度差不超過1的二叉搜索樹。
一個自平衡二叉搜索樹是指其操作都試圖維持平衡的二叉搜索樹。
紅黑樹是一種自平衡二叉搜索樹,Linux主要的平衡二叉樹數據結構就是紅黑樹。
紅黑樹具有以下規則:
所有節點要麽是黑色,或者是紅色
葉子節點都是黑色
葉子節點不包含數據
所有非葉子節點都有兩個子節點
如果一個節點時紅色,則它的子節點一定是黑色
在一個節點到子節點的路徑中,如果總是包含相同數目的黑色節點,則其路徑相比其他路徑是最短的。
根據以上條件,可以保證最深的葉子節點深度不會大於兩倍的最淺葉子節點的深度,所以紅黑樹是半平衡的。
6.5數據結構以及選擇
當你對數據結構的操作主要是遍歷,就使用鏈表,沒有數據結構可以可以提供比線性算法復雜度更好的算法遍歷元素。
如果你的代碼符合生產者-消費者模型,則使用隊列。
如果你需要存儲大量數據,並且檢索迅速,則使用紅黑樹最好。
6.6時間復雜度
1 衡量
logN 對數
n 線性
n的2次方 平方
n的3次方 立方
2的N次方 指數
n! 階乘
第六章:內核數據結構