缘由
最近一段时间想了想红黑树,理解了一下原理之内的,算法导论上已经讲的非常好了,我就不多废话了,所以这是我从nginx中抽取的红黑树的源码,共三分文件,能够单独运行。除了nginx中用于写的红黑树的两份代码以外,主要是就运行实例的main函数文件。红黑树的好处
两附图说清楚,如果我们有序插入1、6、8、11、13、15、17、22、25、27普通二叉查找树的话,会形成下图一样的树:发
这样遍历就没有好好利用了二叉查找树的特性。搜索还是非常慢的。
红黑树就是一种可以自己调节二叉查找树,如果我们把同样的数据、同样的顺序插入到红黑树,那么就形成的树就下面这样的:
注意,这幅图是我写好代码后,用ddd调试时生成了,不像上图一样那么简单,但是很清晰展示了节点与节点间的关系。以及,额外的一个用于存放我们的想要利用红黑树存放的数据。
源代码
共三份文件(没有上传网盘):- mainforRbtree.c
- ngx_rbtree.c
- ngx_rbtree.h
mainforRbtree.c
/**
* 这是抽取出nginx中红黑树的代码,
* 使用红黑树的例子
* 另外两份文件是:ngx_rbtree.c和ngx_rbtree.c
* 注意我修改了添加了很多额外的信息使得这个份代码能够单独运行
*/
#include "ngx_rbtree.c"
typedef struct {
/**
* 这里必须要将红黑树的节点放在结构体的地一个位置
* 便于强制转换直接获得节点
*/
ngx_rbtree_node_t node;
ngx_uint_t mydate; //这是我们想要红黑树携带的数据
}TestRBTreeNode;
int main() {
ngx_rbtree_t tbtree;
ngx_rbtree_node_t sentinel;
//初始化红黑树,并且指定插入方式
//但是真在在插入数据的时候并不会调用这个函数,还是调用
ngx_rbtree_init(&tbtree,&sentinel,ngx_rbtree_insert_value);
//初始化测试节点
TestRBTreeNode testNode[10];
//假设我们这里就存放红黑树的关键字的数值
testNode[0].mydate = 1;
testNode[1].mydate = 6;
testNode[2].mydate = 8;
testNode[3].mydate = 11;
testNode[4].mydate = 13;
testNode[5].mydate = 15;
testNode[6].mydate = 17;
testNode[7].mydate = 22;
testNode[8].mydate = 25;
testNode[9].mydate = 27;
//再给红黑树关键字附上值,并且插入到红黑树中
int i;
for( i = 0; i < 10 ; i++ ){
testNode[i].node.key = testNode[i].mydate;
ngx_rbtree_insert(&tbtree,&testNode[i]);
}
/*获得该红黑树中最小的节点*/
TestRBTreeNode *tmpnode = (TestRBTreeNode *)ngx_rbtree_min(tbtree.root , &sentinel);
printf("%d",tmpnode->mydate);
}
ngx_rbtree.c
#include "ngx_rbtree.h"
/*
* The red-black tree code is based on the algorithm described in
* the "Introduction to Algorithms" by Cormen, Leiserson and Rivest.
*/
static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_node_t **root,
ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node);
static ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_node_t **root,
ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node);
void
ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
ngx_rbtree_node_t *node)
{
ngx_rbtree_node_t **root, *temp, *sentinel;
/* a binary tree insert */
root