红黑树的一个简单实现

(1)理解了节点旋转的一种简单的想法,在指针赋值的时候一定要把所有的节点都要连接好,如果形成循环指针,递归的时候就会死循环。

(2)完全明白了红黑树定义的内涵,使得树到叶子的距离最大值不超过最小值的两倍。最大距离就是黑色节点之间都有红色节点插入。

(3)数据结构尤其是树的变化有很多种情况,测试的时候可以设定特殊的测试环境来进行白盒测试,比如递增插入或者递减插入。

(4)debug的时候在纸上模拟出bug情形,然后再跟踪,减少使用debug的时间,debug观察参数不过是发现问题,通过思考可以发现问题,也可以解决问题。

(5)参考http://www.ibm.com/developerworks/cn/java/j-lo-tree/index.html,节点删除没有实现,看比赛啦。

rbtree.h

#ifndef RBTREE

#define RBTREE

#include<stdio.h>

typedef struct _rbnode{

_rbnode(struct _rbnode * l=NULL,struct _rbnode *r=NULL,struct _rbnode *p=NULL):left(l),right(r),parent(p){}

int key;

int color;

struct _rbnode * left;

struct _rbnode * right;

struct _rbnode * parent;

}rbnode;

extern rbnode* rb_root;

int insert_rbnode(rbnode* root,int key);

int delete_rbnode(rbnode* pnode);

rbnode* find_rbnode(int key);

rbnode* find_rbnode_color(int key,int *c);

rbnode* new_rbnode();

rbnode* successor(rbnode* pnode);

void fix_after_insert(rbnode* new_node);

void fix_after_deletion(rbnode* new_node);

void rotate_left(rbnode* pnode);

void rotate_right(rbnode* pnode);

void print_rb_tree(rbnode* root);

#endif

 

rbtree.cpp

#include"rbtree.h"

#include<stdio.h>

rbnode* rb_root;

rbnode* new_rbnode(){

return new rbnode;

}

int insert_rbnode(rbnode* root,int key){

rbnode *pre=NULL,*p=root,*n;

while(p != NULL){

pre = p;

if(p->key < key) p = p->right;

else if(p->key > key) p = p->left;

else return -1;

}

n = new rbnode;

n->key = key;

n->parent = pre;

if(pre == NULL) {

rb_root = n;

}else{

if(n->key < pre->key) pre->left = n;

else pre->right = n;

}

fix_after_insert(n);

return 1;

}

rbnode* successor(rbnode* pnode){

rbnode* res = pnode->right;

if(res != NULL){

while(res->left != NULL) res=res->left;

}

return res;

}

int delete_rbnode(rbnode* pnode){

rbnode* replace = NULL;

if(pnode->left !=NULL && pnode->right != NULL){

rbnode* s = successor(pnode);

pnode->key = s->key;

pnode = s;

}

replace = pnode->left != NULL ? pnode->left : pnode->right;

if(replace != NULL){

if(pnode->parent == NULL) rb_root = replace;

else if(pnode == pnode->parent->left){

pnode->parent->left = replace;

replace->parent = pnode->parent;

}else if(pnode == pnode->parent->right){

pnode->parent->right = replace;

replace->parent = pnode->parent;

}

}else if(pnode->parent == NULL){

rb_root = NULL;

}else{

if(pnode == pnode->parent->left){

pnode->parent->left = NULL;

}else{

pnode->parent->right = NULL;

}

}

delete pnode;

return 1;

}

rbnode* find_rbnode(int key){

rbnode* pnode = rb_root;

if(pnode != NULL){

while(pnode != NULL){

if(pnode->key < key) pnode = pnode->right;

else if(pnode->key > key) pnode = pnode->left;

else break;

}

}

return pnode;

}

rbnode* find_rbnode_color(int key,int *c){

*c = 0;

rbnode* pnode = rb_root;

if(pnode != NULL){

while(pnode != NULL){

if(pnode->color == 1)

*c += 1;

if(pnode->key < key) pnode = pnode->right;

else if(pnode->key > key) pnode = pnode->left;

else break;

}

}

return pnode;

}

void rotate_left(rbnode* pnode){//左旋转,把节点的右孩子放到自己头上

rbnode* x = pnode;

rbnode* y = x->right;

rbnode* p = pnode->parent;

if(p!=NULL){

if(p->left == x)

p->left = y;

else

p->right = y;

}

y->parent = x->parent;

x->parent = y;

x->right = y->left;

y->left = x;

if(pnode == rb_root)

rb_root = x->parent;

}

void rotate_right(rbnode* pnode){//右旋转,把节点的左孩子放到自己头上

rbnode* x = pnode;

rbnode* y = x->left;

rbnode* p = pnode->parent;

if(p!=NULL){

if(p->left == x)

p->left = y;

else

p->right = y;

}

y->parent = x->parent;

x->parent = y;

x->left = y->right;

y->right = x;

if(pnode == rb_root)

rb_root = x->parent;

}

void fix_after_insert(rbnode* new_node){

new_node->color = 0;

while(new_node != NULL && new_node != rb_root && new_node->parent->color == 0){

if(new_node->parent->parent->left == new_node->parent){//如果父亲是祖父的左孩子

rbnode* sib = new_node->parent->parent->right;

if(sib != NULL && sib->color == 0){//如果父亲的兄弟是红色的

sib->color = 1;

new_node->parent->color = 1;

new_node->parent->parent->color = 0;

new_node = new_node->parent->parent;

}else{//如果父亲的兄弟不存在或者是黑色的

if(new_node == new_node->parent->right){//如果此节点作为右孩子,左转

new_node = new_node->parent;

rotate_left(new_node);

}

rotate_right(new_node->parent->parent);

new_node->parent->color = 1;

new_node->parent->right->color = 0;

}

}else{

rbnode* sib = new_node->parent->parent->left;

if(sib!=NULL && sib->color == 0){

sib->color = 1;

new_node->parent->color = 1;

new_node->parent->parent->color = 0;

new_node = new_node->parent->parent;

}else{

if(new_node == new_node->parent->left){

new_node = new_node->parent;

rotate_right(new_node);

}

rotate_left(new_node->parent->parent);

new_node->parent->color = 1;

new_node->parent->left->color = 0;

}

}

}

rb_root->color = 1;

}

void fix_after_deletion(rbnode* new_node){

}

void print_rb_tree(rbnode* root){

if(root != NULL){

print_rb_tree(root->left);

printf("%d ",root->key);

print_rb_tree(root->right);

}

}

 main.cpp

#include"rbtree.h"

#include<stdlib.h>

int main(){

int i;

for(i=0;i<100;i++){

insert_rbnode(rb_root,i);

}

print_rb_tree(rb_root);

/*for(i=0;i<100;i++){

rbnode * p = find_rbnode(rand()%100);

if(p != NULL) 

delete_rbnode(p);

}*/

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值