modify-rbtree
This commit is contained in:
parent
7f54b96dc7
commit
995a6355bf
Binary file not shown.
Before Width: | Height: | Size: 65 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB |
Binary file not shown.
Before Width: | Height: | Size: 125 KiB |
|
@ -1,534 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rbtree.h"
|
||||
|
||||
#define rb_parent(r) ((r)->parent)
|
||||
#define rb_color(r) ((r)->is_red)
|
||||
#define rb_is_red(r) ((r)->is_red==RED)
|
||||
#define rb_is_black(r) ((r)->is_red==BLACK)
|
||||
#define rb_set_black(r) do { (r)->is_red = BLACK; } while (0)
|
||||
#define rb_set_red(r) do { (r)->is_red = RED; } while (0)
|
||||
#define rb_set_parent(r,p) do { (r)->parent = (p); } while (0)
|
||||
#define rb_set_color(r,c) do { (r)->is_red = (c); } while (0)
|
||||
|
||||
/*
|
||||
* 创建红黑树
|
||||
*/
|
||||
RBRoot* create_rbtree()
|
||||
{
|
||||
RBRoot *root = (RBRoot *)malloc(sizeof(RBRoot));
|
||||
root->node = NULL;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 中序遍历
|
||||
*/
|
||||
static void inorder(RBTree tree)
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
inorder(tree->left_child);
|
||||
printf("key:%d, color: ", tree->key);
|
||||
if(tree->is_red==RED){
|
||||
printf("Red\n");
|
||||
}else{
|
||||
printf("Black\n");
|
||||
}
|
||||
inorder(tree->right_child);
|
||||
}
|
||||
}
|
||||
|
||||
void RBTreeTraversal(RBRoot *root)
|
||||
{
|
||||
printf("---------------------Inorder Traversal-----------------------------\n");
|
||||
if (root)
|
||||
inorder(root->node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 递归查找键值为key的节点
|
||||
*/
|
||||
static Node* search(RBTree x, Type key)
|
||||
{
|
||||
if (x==NULL || x->key==key)
|
||||
return x;
|
||||
|
||||
if (key < x->key)
|
||||
return search(x->left_child, key);
|
||||
else
|
||||
return search(x->right_child, key);
|
||||
}
|
||||
int RBTreeSearch(RBRoot *root, Type key)
|
||||
{
|
||||
if (root)
|
||||
return search(root->node, key)? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 返回tree为根结点的红黑树的最小结点。
|
||||
*/
|
||||
static Node* minimum(RBTree tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return NULL;
|
||||
|
||||
while(tree->left_child != NULL)
|
||||
tree = tree->left_child;
|
||||
return tree;
|
||||
}
|
||||
|
||||
int rbtree_minimum(RBRoot *root, int *val)
|
||||
{
|
||||
Node *node;
|
||||
|
||||
if (root)
|
||||
node = minimum(root->node);
|
||||
|
||||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
*val = node->key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 找结点(x)的后继结点
|
||||
*/
|
||||
static Node* FindSuccessor(RBTree x)
|
||||
{
|
||||
if (x->right_child != NULL)
|
||||
return minimum(x->right_child);
|
||||
Node* y = x->parent;
|
||||
while ((y!=NULL) && (x==y->right_child))
|
||||
{
|
||||
x = y;
|
||||
y = y->parent;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 对红黑树的节点(x)进行左旋转
|
||||
*/
|
||||
static void RBTreeLeftRotate(RBRoot *root, Node *x)
|
||||
{
|
||||
Node *y = x->right_child;
|
||||
x->right_child = y->left_child;
|
||||
if (y->left_child != NULL)
|
||||
y->left_child->parent = x;
|
||||
y->parent = x->parent;
|
||||
|
||||
if (x->parent == NULL)
|
||||
{
|
||||
root->node = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x->parent->left_child == x)
|
||||
x->parent->left_child = y;
|
||||
else
|
||||
x->parent->right_child = y;
|
||||
}
|
||||
|
||||
y->left_child = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
/*
|
||||
* 对红黑树的节点(y)进行右旋转
|
||||
*/
|
||||
static void RBTreeRightRotate(RBRoot *root, Node *y)
|
||||
{
|
||||
Node *x = y->left_child;
|
||||
y->left_child = x->right_child;
|
||||
if (x->right_child != NULL)
|
||||
x->right_child->parent = y;
|
||||
x->parent = y->parent;
|
||||
|
||||
if (y->parent == NULL)
|
||||
{
|
||||
root->node = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y == y->parent->right_child)
|
||||
y->parent->right_child = x;
|
||||
else
|
||||
y->parent->left_child = x;
|
||||
}
|
||||
x->right_child = y;
|
||||
y->parent = x;
|
||||
}
|
||||
|
||||
/*
|
||||
* 红黑树插入修正函数
|
||||
*/
|
||||
static void InsertFixup(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *parent, *gparent;
|
||||
|
||||
// 若“父节点存在,并且父节点的颜色是红色”
|
||||
while ((parent = rb_parent(node)) && rb_is_red(parent))
|
||||
{
|
||||
gparent = rb_parent(parent);
|
||||
|
||||
//若“父节点”是“祖父节点的左孩子”
|
||||
if (parent == gparent->left_child)
|
||||
{
|
||||
// Case 1条件:叔叔节点是红色
|
||||
{
|
||||
Node *uncle = gparent->right_child;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是右孩子
|
||||
if (parent->right_child == node)
|
||||
{
|
||||
Node *tmp;
|
||||
RBTreeLeftRotate(root, parent);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
// Case 3条件:叔叔是黑色,且当前节点是左孩子。
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
RBTreeRightRotate(root, gparent);
|
||||
}
|
||||
else//若“z的父节点”是“z的祖父节点的右孩子”
|
||||
{
|
||||
// Case 1条件:叔叔节点是红色
|
||||
{
|
||||
Node *uncle = gparent->left_child;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是左孩子
|
||||
if (parent->left_child == node)
|
||||
{
|
||||
Node *tmp;
|
||||
RBTreeRightRotate(root, parent);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
RBTreeLeftRotate(root, gparent);
|
||||
}
|
||||
}
|
||||
|
||||
// 将根节点设为黑色
|
||||
rb_set_black(root->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 添加节点
|
||||
*/
|
||||
static void insert_node(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *y = NULL;
|
||||
Node *x = root->node;
|
||||
while (x != NULL)
|
||||
{
|
||||
y = x;
|
||||
if (node->key < x->key)
|
||||
x = x->left_child;
|
||||
else
|
||||
x = x->right_child;
|
||||
}
|
||||
rb_parent(node) = y;
|
||||
|
||||
if (y != NULL)
|
||||
{
|
||||
if (node->key < y->key)
|
||||
y->left_child = node;
|
||||
else
|
||||
y->right_child = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
root->node = node;
|
||||
}
|
||||
node->is_red = RED;
|
||||
InsertFixup(root, node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 创建结点
|
||||
*/
|
||||
static Node* create_rbtree_node(Type key, Node *parent, Node *left_child, Node* right_child)
|
||||
{
|
||||
Node* p;
|
||||
|
||||
if ((p = (Node *)malloc(sizeof(Node))) == NULL)
|
||||
return NULL;
|
||||
p->key = key;
|
||||
p->left_child = left_child;
|
||||
p->right_child = right_child;
|
||||
p->parent = parent;
|
||||
p->is_red = BLACK; // 默认为黑色
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* 新建结点(节点键值为key),并将其插入到红黑树中
|
||||
*/
|
||||
int RBTreeInsert(RBRoot *root, Type key)
|
||||
{
|
||||
Node *node;
|
||||
if (search(root->node, key) != NULL)
|
||||
return -1;
|
||||
if ((node=create_rbtree_node(key, NULL, NULL, NULL)) == NULL)
|
||||
return -1;
|
||||
|
||||
insert_node(root, node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 红黑树删除修正函数
|
||||
*/
|
||||
static void DeleteFixup(RBRoot *root, Node *node, Node *parent)
|
||||
{
|
||||
Node *other;
|
||||
|
||||
while ((!node || rb_is_black(node)) && node != root->node)
|
||||
{
|
||||
if (parent->left_child == node)
|
||||
{
|
||||
other = parent->right_child;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
RBTreeLeftRotate(root, parent);
|
||||
other = parent->right_child;
|
||||
}
|
||||
if ((!other->left_child || rb_is_black(other->left_child)) &&
|
||||
(!other->right_child || rb_is_black(other->right_child)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->right_child || rb_is_black(other->right_child))
|
||||
{
|
||||
rb_set_black(other->left_child);
|
||||
rb_set_red(other);
|
||||
RBTreeRightRotate(root, other);
|
||||
other = parent->right_child;
|
||||
}
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
rb_set_black(other->right_child);
|
||||
RBTreeLeftRotate(root, parent);
|
||||
node = root->node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
other = parent->left_child;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
RBTreeRightRotate(root, parent);
|
||||
other = parent->left_child;
|
||||
}
|
||||
if ((!other->left_child || rb_is_black(other->left_child)) &&
|
||||
(!other->right_child || rb_is_black(other->right_child)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->left_child || rb_is_black(other->left_child))
|
||||
{
|
||||
// Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
|
||||
rb_set_black(other->right_child);
|
||||
rb_set_red(other);
|
||||
RBTreeLeftRotate(root, other);
|
||||
other = parent->left_child;
|
||||
}
|
||||
// Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
rb_set_black(other->left_child);
|
||||
RBTreeRightRotate(root, parent);
|
||||
node = root->node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node)
|
||||
rb_set_black(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除结点
|
||||
*/
|
||||
void rbtree_delete(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *child, *parent;
|
||||
int is_red;
|
||||
if ( (node->left_child!=NULL) && (node->right_child!=NULL) )
|
||||
{
|
||||
Node *replace = node;
|
||||
replace = replace->right_child;
|
||||
while (replace->left_child != NULL)
|
||||
replace = replace->left_child;
|
||||
if (rb_parent(node))
|
||||
{
|
||||
if (rb_parent(node)->left_child == node)
|
||||
rb_parent(node)->left_child = replace;
|
||||
else
|
||||
rb_parent(node)->right_child = replace;
|
||||
}
|
||||
else
|
||||
root->node = replace;
|
||||
child = replace->right_child;
|
||||
parent = rb_parent(replace);
|
||||
is_red = rb_is_red(replace);
|
||||
if (parent == node)
|
||||
{
|
||||
parent = replace;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child)
|
||||
rb_set_parent(child, parent);
|
||||
parent->left_child = child;
|
||||
|
||||
replace->right_child = node->right_child;
|
||||
rb_set_parent(node->right_child, replace);
|
||||
}
|
||||
|
||||
replace->parent = node->parent;
|
||||
replace->is_red = node->is_red;
|
||||
replace->left_child = node->left_child;
|
||||
node->left_child->parent = replace;
|
||||
|
||||
if (is_red == BLACK)
|
||||
DeleteFixup(root, child, parent);
|
||||
free(node);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
if (node->left_child !=NULL)
|
||||
child = node->left_child;
|
||||
else
|
||||
child = node->right_child;
|
||||
|
||||
parent = node->parent;
|
||||
is_red = node->is_red;
|
||||
|
||||
if (child)
|
||||
child->parent = parent;
|
||||
if (parent)
|
||||
{
|
||||
if (parent->left_child == node)
|
||||
parent->left_child = child;
|
||||
else
|
||||
parent->right_child = child;
|
||||
}
|
||||
else
|
||||
root->node = child;
|
||||
|
||||
if (is_red == BLACK)
|
||||
DeleteFixup(root, child, parent);
|
||||
free(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除键值为key的结点
|
||||
*/
|
||||
void RBTreeDelete(RBRoot *root, Type key)
|
||||
{
|
||||
Node *z, *node;
|
||||
|
||||
if ((z = search(root->node, key)) != NULL)
|
||||
rbtree_delete(root, z);
|
||||
}
|
||||
|
||||
/*
|
||||
* 销毁红黑树
|
||||
*/
|
||||
static void rbtree_destroy(RBTree tree)
|
||||
{
|
||||
if (tree==NULL)
|
||||
return ;
|
||||
|
||||
if (tree->left_child != NULL)
|
||||
rbtree_destroy(tree->left_child);
|
||||
if (tree->right_child != NULL)
|
||||
rbtree_destroy(tree->right_child);
|
||||
|
||||
free(tree);
|
||||
}
|
||||
|
||||
void destroy_rbtree(RBRoot *root)
|
||||
{
|
||||
if (root != NULL)
|
||||
rbtree_destroy(root->node);
|
||||
|
||||
free(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* 打印"红黑树"
|
||||
*/
|
||||
static void rbtree_print(RBTree tree, Type key, int direction)
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
if(direction==0) // tree是根节点
|
||||
printf("%2d(B) is root\n", tree->key);
|
||||
else // tree是分支节点
|
||||
printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree)?"R":"B", key, direction==1?"right_child" : "left_child");
|
||||
|
||||
rbtree_print(tree->left_child, tree->key, -1);
|
||||
rbtree_print(tree->right_child,tree->key, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void print_rbtree(RBRoot *root)
|
||||
{
|
||||
if (root!=NULL && root->node!=NULL)
|
||||
rbtree_print(root->node, root->node->key, 0);
|
||||
}
|
|
@ -1,6 +1,15 @@
|
|||
#include <stdio.h>
|
||||
#include "rbtree.h"
|
||||
#include "rbtree.c"
|
||||
#include <stdlib.h>
|
||||
#include "test_rbtree.h"
|
||||
|
||||
#define rb_parent(r) ((r)->parent)
|
||||
#define rb_color(r) ((r)->is_red)
|
||||
#define rb_is_red(r) ((r)->is_red==RED)
|
||||
#define rb_is_black(r) ((r)->is_red==BLACK)
|
||||
#define rb_set_black(r) do { (r)->is_red = BLACK; } while (0)
|
||||
#define rb_set_red(r) do { (r)->is_red = RED; } while (0)
|
||||
#define rb_set_parent(r,p) do { (r)->parent = (p); } while (0)
|
||||
#define rb_set_color(r,c) do { (r)->is_red = (c); } while (0)
|
||||
|
||||
// 默认关键字数组
|
||||
static Type arr[] = {10, 40, 30, 60, 90, 70, 20, 50, 80,
|
||||
|
@ -8,7 +17,531 @@ static Type arr[] = {10, 40, 30, 60, 90, 70, 20, 50, 80,
|
|||
170, 180, 190};
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
|
||||
|
||||
int main(void) {
|
||||
/*
|
||||
* 创建红黑树
|
||||
*/
|
||||
RBRoot* create_rbtree()
|
||||
{
|
||||
RBRoot *root = (RBRoot *)malloc(sizeof(RBRoot));
|
||||
root->node = NULL;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 中序遍历
|
||||
*/
|
||||
static void inorder(RBTree tree)
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
inorder(tree->left_child);
|
||||
printf("key:%d, color: ", tree->key);
|
||||
if(tree->is_red==RED){
|
||||
printf("Red\n");
|
||||
}else{
|
||||
printf("Black\n");
|
||||
}
|
||||
inorder(tree->right_child);
|
||||
}
|
||||
}
|
||||
|
||||
void RBTreeTraversal(RBRoot *root)
|
||||
{
|
||||
printf("---------------------Inorder Traversal-----------------------------\n");
|
||||
if (root)
|
||||
inorder(root->node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 递归查找键值为key的节点
|
||||
*/
|
||||
static Node* search(RBTree x, Type key)
|
||||
{
|
||||
if (x==NULL || x->key==key)
|
||||
return x;
|
||||
|
||||
if (key < x->key)
|
||||
return search(x->left_child, key);
|
||||
else
|
||||
return search(x->right_child, key);
|
||||
}
|
||||
int RBTreeSearch(RBRoot *root, Type key)
|
||||
{
|
||||
if (root)
|
||||
return search(root->node, key)? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 返回tree为根结点的红黑树的最小结点。
|
||||
*/
|
||||
static Node* minimum(RBTree tree)
|
||||
{
|
||||
if (tree == NULL)
|
||||
return NULL;
|
||||
|
||||
while(tree->left_child != NULL)
|
||||
tree = tree->left_child;
|
||||
return tree;
|
||||
}
|
||||
|
||||
int rbtree_minimum(RBRoot *root, int *val)
|
||||
{
|
||||
Node *node;
|
||||
|
||||
if (root)
|
||||
node = minimum(root->node);
|
||||
|
||||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
*val = node->key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 找结点(x)的后继结点
|
||||
*/
|
||||
static Node* FindSuccessor(RBTree x)
|
||||
{
|
||||
if (x->right_child != NULL)
|
||||
return minimum(x->right_child);
|
||||
Node* y = x->parent;
|
||||
while ((y!=NULL) && (x==y->right_child))
|
||||
{
|
||||
x = y;
|
||||
y = y->parent;
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 对红黑树的节点(x)进行左旋转
|
||||
*/
|
||||
static void RBTreeLeftRotate(RBRoot *root, Node *x)
|
||||
{
|
||||
Node *y = x->right_child;
|
||||
x->right_child = y->left_child;
|
||||
if (y->left_child != NULL)
|
||||
y->left_child->parent = x;
|
||||
y->parent = x->parent;
|
||||
|
||||
if (x->parent == NULL)
|
||||
{
|
||||
root->node = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x->parent->left_child == x)
|
||||
x->parent->left_child = y;
|
||||
else
|
||||
x->parent->right_child = y;
|
||||
}
|
||||
|
||||
y->left_child = x;
|
||||
x->parent = y;
|
||||
}
|
||||
|
||||
/*
|
||||
* 对红黑树的节点(y)进行右旋转
|
||||
*/
|
||||
static void RBTreeRightRotate(RBRoot *root, Node *y)
|
||||
{
|
||||
Node *x = y->left_child;
|
||||
y->left_child = x->right_child;
|
||||
if (x->right_child != NULL)
|
||||
x->right_child->parent = y;
|
||||
x->parent = y->parent;
|
||||
|
||||
if (y->parent == NULL)
|
||||
{
|
||||
root->node = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y == y->parent->right_child)
|
||||
y->parent->right_child = x;
|
||||
else
|
||||
y->parent->left_child = x;
|
||||
}
|
||||
x->right_child = y;
|
||||
y->parent = x;
|
||||
}
|
||||
|
||||
/*
|
||||
* 红黑树插入修正函数
|
||||
*/
|
||||
static void InsertFixup(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *parent, *gparent;
|
||||
|
||||
// 若“父节点存在,并且父节点的颜色是红色”
|
||||
while ((parent = rb_parent(node)) && rb_is_red(parent))
|
||||
{
|
||||
gparent = rb_parent(parent);
|
||||
|
||||
//若“父节点”是“祖父节点的左孩子”
|
||||
if (parent == gparent->left_child)
|
||||
{
|
||||
// Case 1条件:叔叔节点是红色
|
||||
{
|
||||
Node *uncle = gparent->right_child;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是右孩子
|
||||
if (parent->right_child == node)
|
||||
{
|
||||
Node *tmp;
|
||||
RBTreeLeftRotate(root, parent);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
// Case 3条件:叔叔是黑色,且当前节点是左孩子。
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
RBTreeRightRotate(root, gparent);
|
||||
}
|
||||
else//若“z的父节点”是“z的祖父节点的右孩子”
|
||||
{
|
||||
// Case 1条件:叔叔节点是红色
|
||||
{
|
||||
Node *uncle = gparent->left_child;
|
||||
if (uncle && rb_is_red(uncle))
|
||||
{
|
||||
rb_set_black(uncle);
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
node = gparent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2条件:叔叔是黑色,且当前节点是左孩子
|
||||
if (parent->left_child == node)
|
||||
{
|
||||
Node *tmp;
|
||||
RBTreeRightRotate(root, parent);
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
|
||||
rb_set_black(parent);
|
||||
rb_set_red(gparent);
|
||||
RBTreeLeftRotate(root, gparent);
|
||||
}
|
||||
}
|
||||
|
||||
// 将根节点设为黑色
|
||||
rb_set_black(root->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 添加节点
|
||||
*/
|
||||
static void insert_node(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *y = NULL;
|
||||
Node *x = root->node;
|
||||
while (x != NULL)
|
||||
{
|
||||
y = x;
|
||||
if (node->key < x->key)
|
||||
x = x->left_child;
|
||||
else
|
||||
x = x->right_child;
|
||||
}
|
||||
rb_parent(node) = y;
|
||||
|
||||
if (y != NULL)
|
||||
{
|
||||
if (node->key < y->key)
|
||||
y->left_child = node;
|
||||
else
|
||||
y->right_child = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
root->node = node;
|
||||
}
|
||||
node->is_red = RED;
|
||||
InsertFixup(root, node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 创建结点
|
||||
*/
|
||||
static Node* create_rbtree_node(Type key, Node *parent, Node *left_child, Node* right_child)
|
||||
{
|
||||
Node* p;
|
||||
|
||||
if ((p = (Node *)malloc(sizeof(Node))) == NULL)
|
||||
return NULL;
|
||||
p->key = key;
|
||||
p->left_child = left_child;
|
||||
p->right_child = right_child;
|
||||
p->parent = parent;
|
||||
p->is_red = BLACK; // 默认为黑色
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* 新建结点(节点键值为key),并将其插入到红黑树中
|
||||
*/
|
||||
int RBTreeInsert(RBRoot *root, Type key)
|
||||
{
|
||||
Node *node;
|
||||
if (search(root->node, key) != NULL)
|
||||
return -1;
|
||||
if ((node=create_rbtree_node(key, NULL, NULL, NULL)) == NULL)
|
||||
return -1;
|
||||
|
||||
insert_node(root, node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 红黑树删除修正函数
|
||||
*/
|
||||
static void DeleteFixup(RBRoot *root, Node *node, Node *parent)
|
||||
{
|
||||
Node *other;
|
||||
|
||||
while ((!node || rb_is_black(node)) && node != root->node)
|
||||
{
|
||||
if (parent->left_child == node)
|
||||
{
|
||||
other = parent->right_child;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
RBTreeLeftRotate(root, parent);
|
||||
other = parent->right_child;
|
||||
}
|
||||
if ((!other->left_child || rb_is_black(other->left_child)) &&
|
||||
(!other->right_child || rb_is_black(other->right_child)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->right_child || rb_is_black(other->right_child))
|
||||
{
|
||||
rb_set_black(other->left_child);
|
||||
rb_set_red(other);
|
||||
RBTreeRightRotate(root, other);
|
||||
other = parent->right_child;
|
||||
}
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
rb_set_black(other->right_child);
|
||||
RBTreeLeftRotate(root, parent);
|
||||
node = root->node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
other = parent->left_child;
|
||||
if (rb_is_red(other))
|
||||
{
|
||||
rb_set_black(other);
|
||||
rb_set_red(parent);
|
||||
RBTreeRightRotate(root, parent);
|
||||
other = parent->left_child;
|
||||
}
|
||||
if ((!other->left_child || rb_is_black(other->left_child)) &&
|
||||
(!other->right_child || rb_is_black(other->right_child)))
|
||||
{
|
||||
rb_set_red(other);
|
||||
node = parent;
|
||||
parent = rb_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other->left_child || rb_is_black(other->left_child))
|
||||
{
|
||||
// Case 3: x的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
|
||||
rb_set_black(other->right_child);
|
||||
rb_set_red(other);
|
||||
RBTreeLeftRotate(root, other);
|
||||
other = parent->left_child;
|
||||
}
|
||||
// Case 4: x的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
|
||||
rb_set_color(other, rb_color(parent));
|
||||
rb_set_black(parent);
|
||||
rb_set_black(other->left_child);
|
||||
RBTreeRightRotate(root, parent);
|
||||
node = root->node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node)
|
||||
rb_set_black(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除结点
|
||||
*/
|
||||
void rbtree_delete(RBRoot *root, Node *node)
|
||||
{
|
||||
Node *child, *parent;
|
||||
int is_red;
|
||||
if ( (node->left_child!=NULL) && (node->right_child!=NULL) )
|
||||
{
|
||||
Node *replace = node;
|
||||
replace = replace->right_child;
|
||||
while (replace->left_child != NULL)
|
||||
replace = replace->left_child;
|
||||
if (rb_parent(node))
|
||||
{
|
||||
if (rb_parent(node)->left_child == node)
|
||||
rb_parent(node)->left_child = replace;
|
||||
else
|
||||
rb_parent(node)->right_child = replace;
|
||||
}
|
||||
else
|
||||
root->node = replace;
|
||||
child = replace->right_child;
|
||||
parent = rb_parent(replace);
|
||||
is_red = rb_is_red(replace);
|
||||
if (parent == node)
|
||||
{
|
||||
parent = replace;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (child)
|
||||
rb_set_parent(child, parent);
|
||||
parent->left_child = child;
|
||||
|
||||
replace->right_child = node->right_child;
|
||||
rb_set_parent(node->right_child, replace);
|
||||
}
|
||||
|
||||
replace->parent = node->parent;
|
||||
replace->is_red = node->is_red;
|
||||
replace->left_child = node->left_child;
|
||||
node->left_child->parent = replace;
|
||||
|
||||
if (is_red == BLACK)
|
||||
DeleteFixup(root, child, parent);
|
||||
free(node);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
if (node->left_child !=NULL)
|
||||
child = node->left_child;
|
||||
else
|
||||
child = node->right_child;
|
||||
|
||||
parent = node->parent;
|
||||
is_red = node->is_red;
|
||||
|
||||
if (child)
|
||||
child->parent = parent;
|
||||
if (parent)
|
||||
{
|
||||
if (parent->left_child == node)
|
||||
parent->left_child = child;
|
||||
else
|
||||
parent->right_child = child;
|
||||
}
|
||||
else
|
||||
root->node = child;
|
||||
|
||||
if (is_red == BLACK)
|
||||
DeleteFixup(root, child, parent);
|
||||
free(node);
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除键值为key的结点
|
||||
*/
|
||||
void RBTreeDelete(RBRoot *root, Type key)
|
||||
{
|
||||
Node *z, *node;
|
||||
|
||||
if ((z = search(root->node, key)) != NULL)
|
||||
rbtree_delete(root, z);
|
||||
}
|
||||
|
||||
/*
|
||||
* 销毁红黑树
|
||||
*/
|
||||
static void rbtree_destroy(RBTree tree)
|
||||
{
|
||||
if (tree==NULL)
|
||||
return ;
|
||||
|
||||
if (tree->left_child != NULL)
|
||||
rbtree_destroy(tree->left_child);
|
||||
if (tree->right_child != NULL)
|
||||
rbtree_destroy(tree->right_child);
|
||||
|
||||
free(tree);
|
||||
}
|
||||
|
||||
void destroy_rbtree(RBRoot *root)
|
||||
{
|
||||
if (root != NULL)
|
||||
rbtree_destroy(root->node);
|
||||
|
||||
free(root);
|
||||
}
|
||||
|
||||
/*
|
||||
* 打印"红黑树"
|
||||
*/
|
||||
static void rbtree_print(RBTree tree, Type key, int direction)
|
||||
{
|
||||
if(tree != NULL)
|
||||
{
|
||||
if(direction==0) // tree是根节点
|
||||
printf("%2d(B) is root\n", tree->key);
|
||||
else // tree是分支节点
|
||||
printf("%2d(%s) is %2d's %6s child\n", tree->key, rb_is_red(tree)?"R":"B", key, direction==1?"right_child" : "left_child");
|
||||
|
||||
rbtree_print(tree->left_child, tree->key, -1);
|
||||
rbtree_print(tree->right_child,tree->key, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void print_rbtree(RBRoot *root)
|
||||
{
|
||||
if (root!=NULL && root->node!=NULL)
|
||||
rbtree_print(root->node, root->node->key, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void){
|
||||
int i, ret;
|
||||
char cmd;
|
||||
RBRoot *root = create_rbtree();
|
||||
|
|
Loading…
Reference in New Issue