红黑树与二叉树

权且当复习数据结构了。。。

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值