(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);
}*/
}