RtlInitializeGenericTable系列函数的总结

来源:互联网 发布:radialindicator.js 编辑:程序博客网 时间:2024/06/10 15:04

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》中发表了它。

节点的平衡因子是它的右子树的高度减去它的左子树的高度。带有平衡因子10或 -1的节点被认为是平衡的。带有平衡因子 -22的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。

这里边的处理二叉树的平衡方法:


在驱动初始化的时候,利用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以及伸展树的实现原理应该清楚。



原创粉丝点击