Directly Add code
/* * 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);}