权且当复习数据结构了。。。
linux内核中有个rbtree改改就能用,stl源码中也有,标准stl中的map和set都只是包装了下rbtree
全部代码:点击打开链接
/*************************************************************
* 作者:陈新
* 邮箱:cx2pirate@gmail.com
* 时间:2014.6.1
* 环境:gcc
* 参考:《算法导论》
* ***********************************************************/
#ifndef _HEADER_RB_TREE_
#define _HEADER_RB_TREE_
typedef int Key; //键值类型
typedef int Data; //其他数据
typedef enum{BLACK,RED} RB_COLOR;
struct rb_node{
struct rb_node *parent;
struct rb_node *right;
struct rb_node *left;
RB_COLOR color;
Key key; //键值
Data data; //数据域
};
struct rb_root{
struct rb_node * rb_node;
};
extern struct rb_node *RB_NIL;
#define rb_parent(r) ((struct rb_node *)((r) ->parent))
#define RB_ROOT (struct rb_root){RB_NIL}
//插入和删除节点
int rb_insert(struct rb_node *,struct rb_root*);
struct rb_node * rb_delete(struct rb_node *,struct rb_root*); //只把node从树上卸下来,并没有释放空间
struct rb_node * rb_search(Key key,struct rb_root*);
/**************************************************************
*和二叉树相同,暂时没有实现,rbtree.c中有几个和下面作用相同的函数
*这里时kernel/include/linux/rbtree.h中的声明...
* ***********************************************************/
//查找前趋和后继节点
struct rb_node *rb_next(const struct rb_node*);
struct rb_node *rb_prev(const struct rb_node*);
struct rb_node *rb_first(const struct rb_node*);
struct rb_node *rb_last(const struct rb_node*);
//后续遍历
struct rb_node *rb_first_postorder(const struct rb_root*);
struct rb_node *rb_next_postorder(const struct rb_node*);
//快速替换某个节点
void rb_replace_node(struct rb_node *victim,struct rb_node *new,struct rb_root *root);
#endif
#include "rbtree.h"
#include <stdio.h>
struct rb_node *RB_NIL = &(struct rb_node){0,0,0,BLACK,0,0};
//node为树内任意右孩子不为RB_NIL的节点
void left_rotate(struct rb_node *node,struct rb_root *root)
{
struct rb_node *rc = node ->right; //rc为node的right child
node ->right = rc ->left;
if(rc ->left != RB_NIL){
rc ->left ->parent = node;
}
rc ->parent = node ->parent;
if(node ->parent == RB_NIL){ //node为root节点
root ->rb_node = rc;
}
else if(node == node ->parent ->left){
node ->parent ->left = rc;
}
else{
node ->parent ->right = rc;
}
rc ->left = node;
node ->parent = rc;
}
//node为树内任意左孩子不为RB_NIL的节点
void right_rotate(struct rb_node *node,struct rb_root *root)
{
struct rb_node *lc = node ->left; //lc为node的left child
node ->left = lc ->righ
if(lc ->right != RB_NIL){ //刚开始直接copy过来,少改了个left,debug long long time...
lc ->right ->parent = node;
}
lc ->parent = node ->parent;
if(node ->parent == RB_NIL){ //node为root节点
root ->rb_node = lc;
}
else if(node == node ->parent ->left){
node ->parent ->left = lc;
}
else{
node ->parent ->right = lc;
}
lc ->right = node;
node ->parent = lc;
}
//非递归版本二叉树查找
//node为根节点,k为键值
//返回k节点指针,如果不存在返回RB_NIL
struct rb_node *rb_search(Key key,struct rb_root *root)
{
struct rb_node *p = root ->rb_node;
while(p != RB_NIL && key != p -> key)
{
p = key < p ->key ? p ->left : p ->right;
}
return p == RB_NIL ? NULL : p;
}
//返回以node为根的子树的最小节点
struct rb_node *rb_minimum(struct rb_node *node)
{
struct rb_node *p = node;
while(p ->left != RB_NIL)
{
p = p ->left;
}
return p;
}
//返回以node为根的子树的最大节点
struct rb_node *rb_maximum(struct rb_node *node)
{
struct rb_node *p = node;
while(p ->right != RB_NIL)
{
p = p ->right;
}
return p;
}
//返回node的后继节点
struct rb_node *tree_successor(struct rb_node *node)
{
struct rb_node *p = node;
if(p ->right != RB_NIL)
{
return rb_minimum(p ->right);
}
struct rb_node *parent = p ->parent;
while(parent != RB_NIL && p == parent ->right)
{
p = parent;
parent = parent ->parent;
}
return parent;
}
//插入节点后红黑树别破坏的性质2和性质4
void rb_insert_fixup(struct rb_node *node,struct rb_root *root)
{
while((rb_parent(node)) ->color == RED){
if(rb_parent(node) == rb_parent(rb_parent(node)) ->left){
struct rb_node *uc = rb_parent(rb_parent(node)) ->right;
if(uc ->color == RED){ //case1:叔叔的颜色也为红色
uc ->color = BLACK;
rb_parent(node) ->color = BLACK;
rb_parent(rb_parent(node)) ->color = RED;
node = rb_parent(rb_parent(node));
}
else{
if(node == rb_parent(node) ->right){ //case2:叔叔为黑色,node为parent的右节点
node = rb_parent(node); //通过左旋变为case3
left_rotate(node,root);
}
rb_parent(node) ->color = BLACK;
rb_parent(rb_parent(node)) ->color = RED;
right_rotate(rb_parent(rb_parent(node)),root);
}
}
else{
struct rb_node *uc = rb_parent(rb_parent(node)) ->left;
if(uc ->color == RED){ //case1:叔叔的颜色也为红色
uc ->color = BLACK;
rb_parent(node) ->color = BLACK;
rb_parent(rb_parent(node)) ->color = RED;
node = rb_parent(rb_parent(node));
}
else{
if(node == rb_parent(node) ->left){ //case2:叔叔为黑色,node为parent的右节点
node = rb_parent(node); //通过左旋变为case3
right_rotate(node,root);
}
rb_parent(node) ->color = BLACK;
rb_parent(rb_parent(node)) ->color = RED;
left_rotate(rb_parent(rb_parent(node)),root);
}
}
}
root ->rb_node ->color = BLACK;
}
//插入一个节点,与二叉树区别不大,最后需要调用rb_insert_fixup修复红黑性质
int rb_insert(struct rb_node *node,struct rb_root *root)
{
struct rb_node *parent = RB_NIL; //node在树中的父亲
struct rb_node *p = root ->rb_node;
while(p != RB_NIL){
parent = p;
if(node ->key < p ->key){
p = p ->left;
}
else if(node ->key > p ->key){
p = p ->right;
}
else{
return 0;
}
}
node ->parent = parent;
if(parent == RB_NIL){
root ->rb_node = node;
}
else if(node ->key < parent ->key){
parent ->left = node;
}
else{
parent ->right = node;
}
node ->left = RB_NIL;
node ->right = RB_NIL;
node ->color = RED;
rb_insert_fixup(node,root);
return 0;
}
void rb_delete_fixup(struct rb_node *node,struct rb_root *root)
{
struct rb_node *sibiling;
while(node != root ->rb_node && node ->color == BLACK){ //node has double black attrubute
if(node == rb_parent(node) ->left){ //!note:node could be RB_NIL
sibiling = rb_parent(node) ->right; //!note:double black node certainly has a brother
if(sibiling ->color == RED){ //case 1:brother's color is red
sibiling ->color = BLACK; //and sibiling has two black child
rb_parent(node) ->color = RED; //aparenter this,case 1 will be turned to
left_rotate(rb_parent(node),root); //case2,case 3 or case 4.
sibiling = rb_parent(node) ->right;
}
if(sibiling ->left ->color == BLACK && sibiling ->right ->color == BLACK){
sibiling ->color = RED;
node = rb_parent(node); //case 2:双重黑色上移到父亲,循环迭代.
}
else{
if(sibiling ->right ->color == BLACK){ //case 3:变为case 4
sibiling ->left ->color = BLACK;
sibiling ->color = RED;
right_rotate(sibiling,root);
sibiling = rb_parent(node) ->right;
}
sibiling ->color = rb_parent(node) ->color; //case 4:
rb_parent(node) ->color = BLACK;
sibiling ->right ->color = BLACK;
left_rotate(rb_parent(node),root);
node = root ->rb_node; //case 4经过此步就结束了
}
}
else{
sibiling = rb_parent(node) ->left; //double black node certainly has a brother
if(sibiling ->color == RED){ //case 1:brother's color is red
sibiling ->color = BLACK; //and sibiling has two black child
rb_parent(node) ->color = RED; //aparenter this,case 1 will be turned to
right_rotate(rb_parent(node),root); //case2,case 3 or case 4.
sibiling = rb_parent(node) ->left;
}
if(sibiling ->left ->color == BLACK && sibiling ->right ->color == BLACK){
sibiling ->color = RED;
node = rb_parent(node); //case 2:double black move up.
}
else{
if(sibiling ->left ->color == BLACK){ //case 3:
sibiling ->right ->color = BLACK;
sibiling ->color = RED;
left_rotate(sibiling,root);
sibiling = rb_parent(node) ->left;
}
sibiling ->color = rb_parent(node) ->color; //case 4:
rb_parent(node) ->color = BLACK;
sibiling ->left ->color = BLACK;
right_rotate(rb_parent(node),root);
node = root ->rb_node; //case 4经过此步就结束了
}
}
}
node ->color = BLACK;
}
struct rb_node * rb_delete(struct rb_node *node,struct rb_root *root)
{
struct rb_node *p,*ps; //p为待删除节点,ps为p的子节点
if(node ->left == RB_NIL || node -> right == RB_NIL){
p = node;
}
else{
p = tree_successor(node);
}
ps = p ->left != RB_NIL ? p ->left : p ->right;
ps ->parent = p ->parent; //different from binary_tree,ps could be NIL
if(p ->parent == RB_NIL){
root ->rb_node = ps;
}
else if(p == rb_parent(p) ->left){
rb_parent(p) ->left = ps;
}
else{
rb_parent(p) ->right = ps;
}
if(p != node){ //复制key域,如果还有其它数据需要一同复制{
node ->key = p ->key;
node ->data = p ->data;
}
if(p ->color == BLACK){ //black node is deleted
rb_delete_fixup(ps,root);
}
return p;
}