Red and Black Tree rbtree realization, authentic nginx. Deepen understanding. DEEPRL Publish time: 2014/05/27 20:04 read: 1117 collection: 6 point praise: 0 Comments: 1
SummaryAs an efficient data structure (a kind of balanced binary tree), the red-black tree (Nginx) is used in the core module (timer, file cache module, etc.).
Rbtree.h #ifndef _rbtree_h_ #define _rbtree_h_ #include <stdlib.h> #include <
stdio.h> #include <string> typedef unsigned int rbtree_key_t;
typedef unsigned char u_char;
typedef struct rbtree_node_s rbtree_node_t; struct rbtree_node_s { rbtree_key_t key;
rbtree_node_t *left;
rbtree_node_t *right;
rbtree_node_t *parent;
u_char color; string data;//
<key,data> };
typedef struct rbtree_s rbtree_t; typedef void (*rbtree_insert_pt) (rbtree_node_t *root,//function pointers enable you to implement custom insertion methods rbtree_node_t *node, rbtree_node_t *sentinel); struct rbtree_s { rbtree_node_t *root; rbtree_node_t *sentinel;//all leaf nodes point to the
sentinel node rbtree_insert_pt insert;
}; Void rbtree_insert_value (Rbtree_node_t *temp, rbtree_node_t *node,
rbtree_node_t *sentinel); #define &NBSP;RBT_RED (node) (node)-> color = 1) #define &NBSP;RBT_BLACK (node) (node)->color = 0 #define &NBSP;RBT_IS_RED (node) (node)->color #define &NBSP;RBT_IS_BLACK (node) (!rbt_is_red (node)) #define &NBSP;RBT_COPY_COLOR (N1,&NBSP;N2) (n1->color = N2->color) #define &NBSP;RBTREE_SENTINEL_INIT (node) rbt_black (node) #define rbtree _init (tree, s, i) \ rbtree_ Sentinel_init (s); \ (tree)->root = s; \ (tree)->sentinel = s; \ (tree)->insert = i #endif//rbtree.cpp # include "Rbtree.h" Static inline void rbtree_left_rotate (rbtree_node_t **root, Rbtree_node_t *sentinel, rbtree_node_t *node);/* Root is a two-level pointer/Static&nbsP;inline void rbtree_right_rotate (Rbtree_node_t **root, rbtree_node_t *sentinel,
rbtree_node_t *node); Void rbtree_insert_fixup (Rbtree_node_t **root, rbtree_node_t *sentinel,
rbtree_node_t *node) { rbtree_node_t *temp; while (node != *root && rbt_is_red (node->parent)) { if (node->parent == node-> Parent->parent->left)//left {
temp = node->parent->parent->right;//Right Uncle //case 1 if (RBT_is_red (temp) {
rbt_black (node->parent); rbt_black (Temp
); rbt_red (node-
>parent->parent); node =
node->parent->parent; } else//black { / /case 2 &nbsP; if (node == node->parent->right)//RR { node =
node->parent;
rbtree_left_rotate (Root, sentinel, node); } //case 3 rbt_black (node->parent)
; rbt_red (node-
>parent->parent); &nbSp; rbtree_right_rotate (root,
Sentinel, node->parent->parent); } &NBSP;&NBSP} else//symmetric { temp = node->parent->parent->left;//left Uncle //case 1 if (rbt_is_red (temp) ) {
rbt_black (node->parent); rbt_blacK (temp); rbt_red (node-
>parent->parent); node =
node->parent->parent; } else//black { / /case 2 if (node == node->parent->left)//ll { node = node->parent;
rbtree_right_rotate (Root, sentinel, node); } //case 3 rbt_black (node->parent)
; rbt_red (node-
>parent->parent); rbtree_left_
Rotate (root, sentinel, node->parent->parent); } } } rbt_black (*root); } void rbtree_insert (Rbtree_t *tree, rbtree_node_t *node) { rbtree_
node_t **root, *temp, *sentinel;
root = &tree->root;
sentinel = tree->sentinel; if (*root == sentinel) {
node->parent = NULL;
node->left = sentinel;
node->right = sentinel;
rbt_black (node);
*root = node;
return;
&NBSP;&NBSP;&NBSP;&NBSP} tree->insert (*root, node, sentinel); /*rbtree-insert-fixup*/ rbtree_insert_fixup (Root, sentinel, node);//The blance operation was encapsulated} Void rbtree_insert_ Value (Rbtree_node_t *temp, rbtree_node_t *node,
Rbtree_node_t *sentinel) { rbtree_node_t **p; //and conventional binary tree insert similar for (;;) { p = (Node->key < temp->key) ? &temp-
>left : &temp->right; if (*p == sentinel) { break;
} temp = *p; &NBSP;&NBSP;&NBSP;&NBSP} *p = node;//Here *p already has the left and right attributes of the child's node and does not have to be judged in the same way as the algorithmic introductory bookProperties, two-level pointers are powerful node->parent = temp;
node->left = sentinel;
node->right = sentinel;
rbt_red (node);
Static inline void Rbtree_left_rotate (Rbtree_node_t **root, rbtree_node_t *sentinel, rbtree_node_t *node) { rbtree_node_
t* tmp; /* |
| x y / \ &nBsp; / \ a y ---left---> x c / \ / \ b c a b
* * /*node = x*/ tmp = node->right;
node->right = tmp->left; //parent Node Settings---3 if (tmp->left != sentinel) { tmp->left->parent = node; } tmp->parent = node->parent; if (node == *root) {
*root = tmp;
&NBSP;&NBSP;&NBSP;&NBSP} else if (Node == node->parent->left) { node->parent->left =
tmp &NBSP;&NBSP;&NBSP;&NBSP} else {
node->parent->right = tmp;
} tmp->left = node;
node->parent = tmp; } static inline