摘要
兹博文探讨四个重点:1、简单介绍红黑树;2、红黑树节点数据结构;3、红黑树节点中父节点指针域和自身节点颜色有机结合;4、定义红黑树和操作树节点父节点指针和节点颜色的接口,包括一系列宏和两个函数。
注:所有代码源自kernel 3.10
前言
援引<Documentation/rbtree.txt>中的一部分,并做简单的翻译(个别地方不太好),姑且作为红黑树博文的开篇。
What are red-black trees, and what are they for?
------------------------------------------------
什么是红黑树?并且他们用于什么?
Red-black trees are a type of self-balancing binary search tree, used for
storing sortable key/value data pairs. This differs from radix trees (which
are used to efficiently store sparse arrays and thus use long integer indexes
to insert/access/delete nodes) and hash tables (which are not kept sorted to
be easily traversed in order, and must be tuned for a specific size and
hash function where rbtrees scale gracefully storing arbitrary keys).
红黑树是一种自平衡二叉搜索树,用于存储可排序的键/数值数据。它不同于基数树
(用来有效地存储稀疏数组,因此使用长整数索来插入/存取/删除节点)和哈希表
(它不用进行排序就可以很容易地按序遍历,但必须设定具体大小和散列函数,而红黑树优
雅的扩展存储任意键)
Red-black trees are similar to AVL trees, but provide faster real-time bounded
worst case performance for insertion and deletion (at most two rotations and
three rotations, respectively, to balance the tree), with slightly slower
(but still O(log n)) lookup time.
红黑树类似于AVL树,但对于插入(至多两次旋转)和删除(至多三次旋转来重新平衡红黑树)
提供最坏情况下实时复杂度的更快的性能,和稍慢的查询时间(依旧是O(log n))
To quote Linux Weekly News:
There are a number of red-black trees in use in the kernel.
The deadline and CFQ I/O schedulers employ rbtrees to
track requests; the packet CD/DVD driver does the same.
The high-resolution timer code uses an rbtree to organize outstanding
timer requests. The ext3 filesystem tracks directory entries in a
red-black tree. Virtual memory areas (VMAs) are tracked with red-black
trees, as are epoll file descriptors, cryptographic keys, and network
packets in the "hierarchical token bucket" scheduler.
援引Linux Weekly News:
deadline和CFQ(Completely Fair Queueing)两种I/O调度,运用rbtree跟踪请求;
CD/DVD块数据驱动器也是如此。高分辨率定时器代码中使用rbtree出色的组织定时器的请求。
Ext3文件系统使用rbtree跟踪目录项。虚拟存储区(VMA)的跟踪,以及epoll的文件描述符,
加密密钥,“分层令牌桶”调度网络数据包也均有rbtree的使用。
1、红黑树节点数据结构
<linux/rbtree.h>
struct rb_node {
unsignedlong __rb_parent_color; //下面详细解析这个变量
structrb_node *rb_right;//右孩子指针域
structrb_