红黑树

来源:互联网 发布:淘宝天猫多久不能追评 编辑:程序博客网 时间:2024/06/03 19:16
/***data structure-->rb_tree**auther-->yejing**data---->2014.8.5**brief:红黑树五大特性1,每个节点都有一个或红或黑的颜色2,根节点是黑色的3,叶节点都是黑的4,如果一个节点是红的,那么它的两个子节点都是黑色的5,对于任意一个节点,它到它的子孙节点的任意一条路径都有相同数目的黑色节点**version->1.0(creat the file)**test pc:ubuntu 12.14*/#include <stdio.h>#include <stdlib.h>enum color_t{BLACK,RED};typedef struct rb_node_t{struct rb_node_t *parent, *left, *right;int data;int  key;color_t color;  }rb_node;static rb_node* create_rb_tree(void){rb_node* root = (rb_node*)malloc(sizeof(rb_node));if(!root)return NULL;memset((char*)root, 0, sizeof(rb_node));root->color = BLACK;root->key = 1;root->data = 0;return root}static rb_node* left_rotate(rb_node* tree, rb_node* node){if(!tree || !node)return NULL;rb_node* right = node->right;//turn right's left subtree to node'snode->right = right->left;if(right->left)//if it is existsright->left->parent = node;if(node == tree)//the node needs rotate is the root of the treenode = right;else{if(node = node->parent->left)//the node needs rotate is the left subtree of its parentnode->parent->left = right;elsenode->parent->right = right;right->parent = node->parent;}//connect right and noderight->left = node;node->parent = right;return tree;}static rb_node* right_rotate(rb_node* tree, rb_node* node){if(!tree || !node)return NULL;rb_node* left = node->left;node->left = left->right;if(left->right)left->right->parent = node;if(node == tree)tree = left;else{if(node->parent->right = node)node->parent->right = left;elsenode->parent->left = left;left->parent = node->parent;}node->parent = left;left->right = node;return tree;}static rb_node* search_pos(rb_node* tree, int key, int* match){if(!tree)return NULL;rb_node* tmp = tree;while(tmp){if(tmp->key < key)tmp = tmp->right;else if(tmp->key > key)tmp = tmp->left;else{*match = 1;return tmp;}}*match = 0;return tmp;}static rb_node* rb_new_node(int key, int data){rb_node* tmp = (rb_node*)malloc(sizeof(rb_node));if(!tmp)return NULL;tmp->key = key;tmp->data = data;tmp->parent = tmp->left = tmp->right = NULL;return tmp;}void rb_insert_fixup(rb_node* tree, rb_node* node){if(!tree || !node)return;rb_node *parent, *uncle, *gparent, *tmp;while(node->parnet && (parent = node->parent) && (parent->color == RED))//node的父节点存在,且为红色{gparent = parent->parent;//定义祖父节点if(gparent && parent == gparent->left)//node的父亲是其祖父的左孩子{uncle = gparent->right;//定义叔父节点,此时叔父节点为其祖父的右孩子if(uncle && uncle->color == RED){parent->color = BLACK;uncle->color = BLACK;gparent->color = RED;node = gparent;}else{//uncle为黑色if(node == parent->right){//node为其父的右孩子tree = left_rotate(tree, node);tmp = parent;parent = node;node = tmp;}parent->color = BLACK;gparent->color = RED;tree = right_rotate(tree, node);}}else//node的父亲是其祖父的右孩子{if(gparent){uncle = gparent->left;//uncle为其祖父的左孩子if(uncle && uncle->color == RED){parent->color = BLACK;uncle->color = BLACK;gparent->color = RED;node = gparent;}else{//uncle为黑色if(node == parent->left)//node为其父的左孩子{tree = right_rotate(tree, node);tmp = parent;parent = node;node = tmp;}parent->color = BLACK;gparent->color = RED;tree = left_rotate(tree, node);}}}}//end of while()tree->color = BLACK;return tree;}static rb_node* rb_node_insert(rb_node* tree, int key){if(!tree)return NULL;rb_node* tmp;rb_node* node;int is_match = 0;tmp = search_pos(tree, key, &is_match);if(!tmp)return NULL;node = rb_new_node(key, 1);if(!node)return tree;node->key = key;node->color = RED;node->parent = NULL;node->left = NULL;node->right = NULL;if(key < tmp->key)tmp->left = node;elsetmp->right = node;rb_insert_fixup(tree, node);return tree;}/*删除较插入要复杂一些,加上一份伪代码分析RB-DELETE(T, z) 1 if left[z] = nil[T] or right[z] = nil[T]//有最多一个儿子 2    then y ← z 3    else y ← TREE-SUCCESSOR(z)//有两个儿子,取其右子树的最小值  4 if left[y] ≠ nil[T]//如果y的左子树非空 5    then x ← left[y] 6    else x ← right[y]  7 p[x] ← p[y]//处理y的父亲与其儿子之间的关系  8 if p[y] = nil[T]//如果y的父亲为空,即y为跟节点 9    then root[T] ← x10    else if y = left[p[y]]//y是其父亲的左孩子11            then left[p[y]] ← x12            else right[p[y]] ← x//y是其父亲的右孩子13 if y ≠ z14    then key[z] ← key[y]15         copy y's satellite data into z16 if color[y] = BLACK               //如果y是黑色的,17    then RB-DELETE-FIXUP(T, x)   //则调用RB-DELETE-FIXUP(T, x) 18 return y              //如果y不是黑色,是红色的,则当y被删除时,红黑性质仍然得以保持。不做操作,返回。//理由://1,树中各节点的黑高度没有变化//2,不存在两个相邻的红色节点//3,如果y是红色的,就不可能是根,故根仍然是黑色的*/ rb_node* rb_delete(rb_node* tree, rb_node* node){if(!tree || !node)return tree;}

0 0
原创粉丝点击