1 紅黑樹的定義
(1)每個節點或者為黑色,或者為紅色。
(2)根必須為黑色。
(3)每個葉子節點(不包含關鍵字的節點)都是黑色。
(4)如果有一個節點是紅色,那么它的兩個兒子都是黑色。
(5)對於每個節點,從該節點出發到其子孫節點的所有路徑上包含相同數目的黑節點。
滿足上面5個條件的樹就是一顆紅黑樹,紅黑樹有着很好的性質,它類似於平衡二叉樹(AVL)。一顆紅黑樹的高度不會超過2lg(n+1),而且插入和刪除操作較AVL更快,由於它分別最多做2次和3次旋轉來維護樹的性質,所以在linux內核中大量使用了紅黑樹,如ext3文件系統中使用紅黑色來記錄目錄項,虛擬內存區也是使用它來記錄的。
2 linux內核實現的紅黑樹函數調用關系
linux3.7.4內核實現紅黑樹的的文件是:include/linux/rbtree.h,include/linux/rbtree_augmented.h,lib/rbtree.c。linux3.7.4內核除了有紅黑色的基本功能,而且還基於基本的紅黑樹實現了擴展的紅黑樹。rbtree.h頭文件定義的就是基本的紅黑樹,rbtree_augmented.h頭文件定義了擴展的紅黑樹,rbtree.c是對擴展紅黑樹的實現,由於擴展紅黑色也可以用來實現基本紅黑色。測試文件在lib/rbtree_test.c中。下面描述的是在測試文件中函數的調用關系。
2.1 普通的rbtree函數調用關系
插入節點
刪除節點
2.2 擴展的rbtree函數調用關系
插入節點
刪除節點
2 函數說明
insert函數:查找插入點,調用rb_link_node插入rb樹中,調用rb_insert_color調整rb樹的顏色。rb_insert_color函數直接調用__rb_insert,並將dummy_rotate(不做任何事)的回調函數傳給__rb_insert。__rb_insert函數做主要是做rb樹顏色的調整。
insert_augmented查找插入點,更新擴展域,調用rb_link_node插入rb樹中,調用rb_insert_augmented調整rb樹的顏色,並將augment_callbacks回調函數結構體傳給rb_insert_augmented。rb_insert_augmented調用__rb_insert_augmented,將augment_callbacks中的rotate函數傳給__rb_insert_augmented。_rb_insert_augmented直接調用__rb_insert。
erase函數直接調用rb_erase函數。rb_erase函數調用rb_erase_augmented,並將dummy_callbacks回調函數結構體傳給rb_erase_augmented。rb_erase_augmented函數主要做節點的刪除,並調用__rb_erase_color做rb樹顏色的調整。__rb_erase_color主要做顏色的調整。
erase_augmented函數直接調用rb_erase_augmented函數,並將augment_callbacks回調函數結構體傳給rb_erase_augmented。其它和上面是一樣的。
3 擴展紅黑色流程圖
插入模塊
刪除模塊
刪除模塊中的顏色調整