算法导论C语言实现: 红黑(red-black tree)

来源:互联网 发布:云计算安全体系架构 编辑:程序博客网 时间:2024/05/17 09:07

一、五条性质

1. Every node is either red or black.
2. The root is black.
3. Every leaf (NIL ) is black.
4. If a node is red, then both its children are black.
5. For each node, all simple paths from the node to descendant leaves contain the same number of black nodes.
 


二、头文件

#ifndef __IA_REDBLACK_TREE_H__#define __IA_REDBLACK_TREE_H__#include <common.h>typedef struct _rb_tree_node_t {enum _rb_tree_color{red,black,} color;int key;struct _rb_tree_node_t *left;struct _rb_tree_node_t *right;struct _rb_tree_node_t *p;} rb_tree_node_t;typedef struct _rb_tree_t {rb_tree_node_t *root;rb_tree_node_t* nil;rb_tree_node_t _nil;}rb_tree_t;void ia_rb_tree_init(rb_tree_t *T);void ia_rb_tree_inorder_walk(rb_tree_t *T, rb_tree_node_t *x, FILE *f);void ia_rb_tree_insert(rb_tree_t *T, rb_tree_node_t *z);void ia_rb_tree_delete(rb_tree_t *T, rb_tree_node_t *z);#endif

二、初始化及遍历

void ia_rb_tree_init(rb_tree_t *T){T->nil = &T->_nil;T->root = T->nil;T->_nil.color = black;T->_nil.p = T->nil;T->_nil.left = T->nil;T->_nil.right = T->nil;}void ia_rb_tree_inorder_walk(rb_tree_t *T, rb_tree_node_t *x, FILE *f){const char* s_1_b = "child {\nnode [arn_b] {";const char* s_1_r = "child {\nnode [arn_r] {";const char* s_1_space = "child {\nnode [arn_x] {";const char* s_2 = "}\n";char s_v[20];if (x != T->nil) {if (f == NULL) {ia_rb_tree_inorder_walk(T, x->left, f);TRACE(" %d", x->key);ia_rb_tree_inorder_walk(T, x->right, f);} else {sprintf_s(s_v, sizeof(s_v), "%d", x->key);if (x->color == black) {fputs(s_1_b, f);} else {fputs(s_1_r, f);}fputs(s_v, f);fputs(s_2, f);//print childrenia_rb_tree_inorder_walk(T, x->left, f);ia_rb_tree_inorder_walk(T, x->right, f);fputs(s_2, f);}} else {if (f != NULL) {fputs(s_1_space, f);fputs(s_2, f);fputs(s_2, f);}}}//x must not be nilrb_tree_node_t *ia_rb_tree_minimum(rb_tree_t *T, rb_tree_node_t *x){while (x->left != T->nil) {x = x->left;}return x;}

三、插入

//=========================================//      |    LEFT-ROTATE(T,x)     |//     (y)   <---------------    (x)//     / \                       / \//   (x)  γ  --------------->   α  (y)//   / \     RIGHT-ROTATE(T,y)     / \//  α   β                         β   γ//=========================================void ia_rb_tree_left_rotate(rb_tree_t *T, rb_tree_node_t *x){//TODO: if y == T->nil ??rb_tree_node_t *y = x->right;x->right = y->left;if (y->left != T->nil) {y->left->p = x;}y->p = x->p;if (x->p == T->nil) {T->root = y;} else if (x == x->p->left) {x->p->left = y;} else {x->p->right = y;}y->left = x;x->p = y;}void ia_rb_tree_right_rotate(rb_tree_t *T, rb_tree_node_t *y){//TODO: if x == T->nil ??rb_tree_node_t *x = y->left;y->left = x->right;if (x->right != T->nil) {x->right->p = y;}x->p = y->p;if (y->p == T->nil) {T->root = x;} else if (y == y->p->left) {y->p->left = x;} else {y->p->right = x;}x->right = y;y->p = x;}void ia_rb_tree_fixup(rb_tree_t *T, rb_tree_node_t *z){rb_tree_node_t *y;while (z->p->color == red) {if (z->p == z->p->p->left) {y = z->p->p->right;if (y->color == red) {z->p->color = black;y->color = black;z->p->p->color = red;z = z->p->p;} else {if (z == z->p->right) {z = z->p;ia_rb_tree_left_rotate(T, z);} else {z->p->color = black;z->p->p->color = red;ia_rb_tree_right_rotate(T, z->p->p);}}} else {y = z->p->p->left;if (y->color == red) {z->p->color = black;y->color = black;z->p->p->color = red;z = z->p->p;} else {if (z == z->p->left) {z = z->p;ia_rb_tree_right_rotate(T, z);} else {z->p->color = black;z->p->p->color = red;ia_rb_tree_left_rotate(T, z->p->p);}}}}T->root->color = black;}void ia_rb_tree_insert(rb_tree_t *T, rb_tree_node_t *z){rb_tree_node_t *y = T->nil;rb_tree_node_t *x = T->root;while (x != T->nil) {y = x;if (z->key < x->key) {x = x->left;} else {x = x->right;}}z->p = y;if (y == T->nil) {T->root = z;} else if (z->key < y->key) {y->left = z;} else {y->right = z;}z->left = T->nil;z->right = T->nil;z->color = red;ia_rb_tree_fixup(T, z);}




四、删除

//replace u with vvoid ia_rb_tree_transplant(rb_tree_t *T, rb_tree_node_t *u, rb_tree_node_t *v){if (u->p == T->nil) {T->root = v;} else if (u == u->p->left) {u->p->left = v;} else {u->p->right = v;}v->p = u->p;}void ia_rb_tree_delete_fixup(rb_tree_t *T, rb_tree_node_t *x){rb_tree_node_t *w;while (x != T->root && x->color == black) {if (x == x->p->left) {w = x->p->right;if (w->color == red) {//case 1w->color = black;x->p->color = red;ia_rb_tree_left_rotate(T, x->p);w = x->p->right;}if (w->left->color == black && w->right->color == black) {//case 2w->color = red;x = x->p;} else if (w->right->color == black) {//case 3w->left->color = black;w->color = red;ia_rb_tree_right_rotate(T, w);w = x->p->right;} else {//case 4w->color = x->p->color;x->p->color = black;w->right->color = black;ia_rb_tree_left_rotate(T, x->p);x = T->root;}} else {w = x->p->left;//case 1if (w->color == red) {w->color = black;x->p->color = red;ia_rb_tree_right_rotate(T, x->p);w = x->p->left;}if (w->left->color == black && w->right->color == black) {//case 2w->color = red;x = x->p;} else if (w->left->color == black) {//case 3w->right->color = black;w->color = red;ia_rb_tree_left_rotate(T, w);w = x->p->left;} else {//case 4w->color = x->p->color;x->p->color = black;w->left->color = black;ia_rb_tree_right_rotate(T, x->p);x = T->root;}}}x->color = black;}void ia_rb_tree_delete(rb_tree_t *T, rb_tree_node_t *z){rb_tree_node_t *y = z;rb_tree_node_t *x;enum _rb_tree_color y_original_color = z->color;if (z->left == T->nil) {x = z->right;ia_rb_tree_transplant(T, z, z->right);} else if (z->right == T->nil) {x= z->left;ia_rb_tree_transplant(T, z, z->left);} else {y = ia_rb_tree_minimum(T, z->right);y_original_color = y->color;x = y->right;if (y->p == z) {x->p = y;// x can be T->nil, and need to set parent to y} else {ia_rb_tree_transplant(T, y, y->right);y->right = z->right;y->right->p = y;}ia_rb_tree_transplant(T, z, y);y->left = z->left;y->left->p = y;y->color = z->color;}if ( y_original_color == black) {ia_rb_tree_delete_fixup(T, x);}}




五、脚本

create_tex.bat

rem %1 node filename, %2 out file indextype tex_head.txt > ./latex_aux/%2.textype %1 >> ./latex_aux/%2.textype tex_tail.txt >> ./latex_aux/%2.texpdflatex.exe --output-directory=./latex_aux --file-line-error --interaction=nonstopmode ./latex_aux/%2.tex

tex_head.txt & tex_tail.txt 请参考http://blog.csdn.net/v2nero/article/details/17893429 中tikz脚本


六、简单测试

#include <ia_include.h>#define TEST_IASTACK_SIZE10#define TEST_IAQUEUE_SIZE10#define TEST_IABINARYTREE_NODES20void my_tree_walk(rb_tree_t *T, rb_tree_node_t *x, const char* filename){FILE *f_out = NULL;char cmd[1024];static count = 0;if (filename == NULL) {ia_rb_tree_inorder_walk(T, x, NULL);return;}f_out = fopen(filename, "w+");if (f_out == NULL) {return;}ia_rb_tree_inorder_walk(T, x, f_out);fclose(f_out);sprintf_s(cmd, sizeof(cmd), "call create_tex.bat %s %s.%02d", filename, filename,count++);system(cmd);//system("pause");}void main(){int i = 0;const char * filename = "out.txt";rb_tree_t T;rb_tree_node_t t_nodes[TEST_IABINARYTREE_NODES];int nodes_v[TEST_IABINARYTREE_NODES] = { 5,  3,  4,  8,  1, 20, 33, 30, 34, 28,  8, 33, 11, 24, 11, 10, 12, 18, 22, 23 };/*int nodes_v[TEST_IABINARYTREE_NODES] = { 5,  3,  4,  8,  1, 20, 33, 30, 34, 28,  8, 33, 11, 24, 11, 10, 12, 18, 22, 23, 10, 99, 88, 77, 20,  8,  7, 20,  3, 19};*/ia_rb_tree_init(&T);memset(t_nodes, 0, sizeof(t_nodes));for (i = 0; i < sizeof(t_nodes)/sizeof(rb_tree_node_t); ++i) {t_nodes[i].key = nodes_v[i];ia_rb_tree_insert(&T, &t_nodes[i]);my_tree_walk(&T, T.root, "insert.txt");}my_tree_walk(&T, T.root, NULL);my_tree_walk(&T, T.root, filename);printf("\n\n");//ia_rb_tree_delete(&T, &t_nodes[5]);for (i = sizeof(t_nodes)/sizeof(rb_tree_node_t); i > 0; --i) {ia_rb_tree_delete(&T, &t_nodes[i-1]);my_tree_walk(&T, T.root, filename);}my_tree_walk(&T, T.root, NULL);//my_tree_walk(&T, T.root, filename);printf("\n\n");printf("Terminated!\n");system("pause");}

七、结果


0 0
原创粉丝点击