直接上代码
/*
* bst.h
*
* Created on: Jun 20, 2014
* Author: buyuanyuan
*/
#ifndef BST_H_
#define BST_H_
#include <stdint.h>
#include <stdbool.h>
typedef enum Color {
RED = 0,
BLACK = 1
} Color;
typedef struct Node {
char *key;
Color color;
uint64_t value;
struct Node *left, *right, *parent;
} RBT;
RBT *rbt_insert(RBT *root, char *key, uint64_t value);
uint64_t rbt_search(RBT *root, char *key);
RBT* rbt_delete(RBT *root, char *key);
uint8_t rbt_destory(RBT *root);
#endif /* BST_H_ */
/*
* RBT.c
*
* Created on: Jun 20, 2014
* Author: buyuanyuan
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "rbt.h"
static RBT *rotate_left(RBT *node, RBT *root)
{
RBT* right = node->right;
if((node->right = right->left)) {
right->left->parent = node;
}
right->left = node;
if((right->parent = node->parent)) {
if(node == node->parent->right) {
node->parent->right = right;
} else {
node->parent->left = right;
}
} else {
root = right;
}
node->parent = right;
return root;
}
static RBT *rotate_right(RBT *node, RBT *root)
{
RBT* left = node->left;
if((node->left = left->right)) {
left->right->parent = node;
}
left->right = node;
if((left->parent = node->parent)) {
if(node == node->parent->right) {
node->parent->right = left;
} else {
node->parent->left = left;
}
} else {
root = left;
}
node->parent = left;
return root;
}
static RBT *insert_case(RBT *node, RBT *root)
{
RBT *parent, *gparent, *uncle, *tmp;
while ((parent = node->parent) && parent->color == RED){
gparent = parent->parent;
if (parent == gparent->left){
uncle = gparent->right;
if (uncle && uncle->color == RED){
uncle->color = BLACK;
parent->color = BLACK;
gparent->color = RED;
node = gparent;
}else{
if (parent->right == node){
root = rotate_left(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->color = BLACK;
gparent->color = RED;
root = rotate_right(gparent, root);
}
}else{
uncle = gparent->left;
if (uncle && uncle->color == RED){
uncle->color = BLACK;
parent->color = BLACK;
gparent->color = RED;
node = gparent;
}else{
if (parent->left == node){
root = rotate_right(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->color = BLACK;
gparent->color = RED;
root = rotate_left(gparent, root);
}
}
}
root->color = BLACK;
return root;
}
static RBT *delete_case(RBT *node, RBT *parent, RBT *root)
{
RBT *other, *o_left, *o_right;
while((!node || node->color == BLACK) && node != root) {
if(parent->left == node) {
other = parent->right;
if(other->color == RED) {
other->color = BLACK;
parent->color = RED;
root = rotate_left(parent, root);
other = parent->right;
}
if((!other->left || other->left->color == BLACK) &&
(!other->right || other->right->color == BLACK)) {
other->color = RED;
node = parent;
parent = node->parent;
} else {
if(!other->right || other->right->color == BLACK) {
if((o_left = other->left)) {
o_left->color = BLACK;
}
other->color = RED;
root = rotate_right(other, root);
other = parent->right;
}
other->color = parent->color;
parent->color = BLACK;
if(other->right) {
other->right->color = BLACK;
}
root = rotate_left(parent, root);
node = root;
break;
}
} else {
other = parent->left;
if(other->color == RED) {
other->color = BLACK;
parent->color = RED;
root = rotate_right(parent, root);
other = parent->left;
}
if((!other->left || other->left->color == BLACK) &&
(!other->right || other->right->color == BLACK)) {
other->color = RED;
node = parent;
parent = node->parent;
} else {
if(!other->left || other->left->color == BLACK) {
if((o_right = other->right)) {
o_right->color = BLACK;
}
other->color = RED;
root = rotate_left(other, root);
other = parent->left;
}
other->color = parent->color;
parent->color = BLACK;
if(other->left) {
other->left->color = BLACK;
}
root = rotate_right(parent, root);
node = root;
break;
}
}
}
if(node) {
node->color = BLACK;
}
return root;
}
static RBT *search_data(char *key, RBT *root, RBT **save)
{
if(root == NULL) {
return NULL;
}
RBT *node = root, *parent = NULL;
int64_t ret;
while (node) {
parent = node;
ret = strcmp(node->key, key);
if (0 < ret) {
node = node->left;
} else if (0 > ret) {
node = node->right;
} else {
return node;
}
}
if (save) {
*save = parent;
}
return NULL;
}
static uint8_t destory_all(RBT *root)
{
while(root != NULL) {
root = delete(root, root->key);
}
if(root == NULL) {
return 1;
} else {
return 0;
}
}
RBT* rbt_insert(RBT *root, char *key, uint64_t data)
{
RBT *parent = NULL;
RBT *node = NULL;
if ((node = search_data(key, root, &parent))) {
return root;
}
node = (RBT *)malloc(sizeof(RBT));
if(!node) {
printf("malloc error!");
exit(-1);
}
node->key = (char *)malloc(strlen(key) + 1);
memset(node->key, strlen(key)+1, 0);
strcpy(node->key, key);
node->value = data;
node->parent = parent;
node->left = node->right = NULL;
node->color = RED;
if (parent) {
if(strcmp(parent->key, key)> 0) {
parent->left = node;
} else {
parent->right = node;
}
} else {
root = node;
}
return insert_case(node, root);
}
uint64_t rbt_search(RBT *root, char *key)
{
RBT *node = search_data(key, root, NULL);
if(node) {
return node->value;
} else {
return -1;
}
}
RBT *rbt_delete(RBT *root, char *key)
{
RBT *child, *parent, *old, *left, *node;
Color color;
if (!(node = search_data(key, root, NULL))) {
printf("key %s is not exist!\n", key);
return root;
}
old = node;
if (node->left && node->right) {
node = node->right;
while ((left = node->left) != NULL) {
node = left;
}
child = node->right;
parent = node->parent;
color = node->color;
if (child) {
child->parent = parent;
}
if (parent) {
if (parent->left == node) {
parent->left = child;
} else {
parent->right = child;
}
} else {
root = child;
}
if (node->parent == old) {
parent = node;
}
node->parent = old->parent;
node->color = old->color;
node->right = old->right;
node->left = old->left;
if (old->parent) {
if (old->parent->left == old) {
old->parent->left = node;
} else {
old->parent->right = node;
}
} else {
root = node;
}
old->left->parent = node;
if(old->right) {
old->right->parent = node;
}
} else {
if (!node->left) {
child = node->right;
}
else if (!node->right) {
child = node->left;
}
parent = node->parent;
color = node->color;
if (child) {
child->parent = parent;
}
if (parent) {
if (parent->left == node) {
parent->left = child;
} else {
parent->right = child;
}
} else {
root = child;
}
}
free(old->key);
free(old);
if (color == BLACK) {
root = delete_case(child, parent, root);
}
return root;
}
uint8_t rbt_destory(RBT *root)
{
return destory_all(root);
}