码迷,mamicode.com
首页 > 其他好文 > 详细

红黑树实现

时间:2014-07-01 06:11:04      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:红黑树

直接上代码


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


红黑树实现,布布扣,bubuko.com

红黑树实现

标签:红黑树

原文地址:http://blog.csdn.net/xiaoyeyopulei/article/details/35998273

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!