Windows 驅動中使用伸展樹(Splay Tree)或者平衡樹來儲存資料,加快資料的查詢速度的方法總結。
伸展樹
維基百科,自由的百科全書
伸展樹(Splay Tree)是一種二叉排序樹,它能在O(log n)內完成插入、尋找和刪除操作。它由Daniel Sleator和Robert Tarjan創造。
它的優勢在於不需要記錄用於平衡樹的冗餘資訊。
在伸展樹上的一般操作都基於伸展操作。
假設想要對一個二叉尋找樹執行一系列的尋找操作。為了使整個尋找時間更小,被查頻率高的那些條目就應當經常處於靠近樹根的位置。於是想到設計一個簡 單方法, 在每次尋找之後對樹進行重構,把被尋找的條目搬移到離樹根近一些的地方。splay tree應運而生。splay tree是一種自調整形式的二叉尋找樹,它會沿著從某個節點到樹根之間的路徑,通過一系列的旋轉把這個節點搬移到樹根去。
個人總結:這是一種局部最優的思想,是區別於平衡樹的平均思想的。。。
AVL樹
維基百科,自由的百科全書
非AVL樹的例子
同一個樹在高度平衡之後的樣子
在電腦科學中,AVL樹是最先發明的自平衡二叉尋找樹。在AVL樹中任何節點的兩個子樹的高度最大差別為一,所以它也被稱為高度平衡樹。尋找、插入和刪除在平均和最壞情況下都是O(log n)。增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。AVL樹得名於它的發明者G.M. Adelson-Velsky和E.M. Landis,他們在1962年的論文《An algorithm for the organization of information》中發表了它。
節點的平衡因子是它的右子樹的高度減去它的左子樹的高度。帶有平衡因子1、0或 -1的節點被認為是平衡的。帶有平衡因子 -2或2的節點被認為是不平衡的,並需要重新平衡這個樹。平衡因子可以直接儲存在每個節點中,或從可能儲存在節點中的子樹高度計算出來。
這裡邊的處理二叉樹的平衡方法:
在驅動初始化的時候,利用RtlInitializeGenericTable初始化相關的資訊,這裡邊包括關聯相關的函數:
VOID
RtlInitializeGenericTable(
__out PRTL_GENERIC_TABLE Table,
__in PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
__in PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
__in PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
__in_opt PVOID TableContext
);
第一個參數,是一個已經分配了儲存空間的指標,一般而言,我們都是利用後配列表對其進行分配空間的。
最後一個參數一般:NULL
第二個到第四個參數是我們要註冊的函數:
RTL_GENERIC_COMPARE_RESULTS
RoutineName (
__in struct _RTL_GENERIC_TABLE *Table,
__in PVOID FirstStruct,
__in PVOID SecondStruct
);
PVOID
RoutineName (
__in struct _RTL_GENERIC_TABLE *Table,
__in CLONG ByteSize
);
VOID
RoutineName (
__in struct _RTL_GENERIC_TABLE *Table,
__in PVOID Buffer
);
在使用這一系列的函數時,具體參看WDK即可,但是,需要說明的是,對AVL以及伸展樹的實現原理應該清楚。