红黑树实现

直接上代码


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的红黑树实现主要是通过对节点进行变色和旋转来维持其特性。具体实现可以参考以下步骤: 1.定义红黑树节点类,包括节点值、颜色、左右子节点等属性。 2.定义红黑树类,包括根节点、插入节点、删除节点等方法。 3.在插入节点时,根据其父节点和父节点的兄弟节点进行变色和旋转,以维持红黑树的特性。 4.在删除节点时,同样需要进行变色和旋转,以保证删除后的树仍然是一颗红黑树。 以下是一个简单的Java红黑树实现示例: ```java public class RBNode<T extends Comparable<T>> { boolean color;//颜色 T key;//关键字(键值) RBNode<T> left;//左子节点 RBNode<T> right;//右子节点 RBNode<T> parent;//父节点 public RBNode(boolean color, T key, RBNode<T> parent, RBNode<T> left, RBNode<T> right) { this.color = color; this.key = key; this.parent = parent; this.left = left; this.right = right; } } public class RBTree<T extends Comparable<T>> { private RBNode<T> root;//根节点 //插入节点 public void insert(T key) { RBNode<T> node = new RBNode<T>(false, key, null, null, null); if (node != null) { insert(node); } } //插入节点 private void insert(RBNode<T> node) { RBNode<T> current = null;//当前节点 RBNode<T> x = this.root;//从根节点开始查找 //查找插入位置 while (x != null) { current = x; if (node.key.compareTo(x.key) < 0) { x = x.left; } else { x = x.right; } } node.parent = current; if (current != null) { if (node.key.compareTo(current.key) < 0) { current.left = node; } else { current.right = node; } } else { this.root = node; } //修正红黑树 insertFixUp(node); } //修正红黑树 private void insertFixUp(RBNode<T> node) { RBNode<T> parent, gparent;//父节点和祖父节点 //需要修正的条件:父节点存在,且父节点的颜色是红色 while (((parent = parentOf(node)) != null) && isRed(parent)) { gparent = parentOf(parent);//祖父节点 //父节点是祖父节点的左子节点 if (parent == gparent.left) { RBNode<T> uncle = gparent.right;//叔叔节点 //case1:叔叔节点也是红色 if ((uncle != null) && isRed(uncle)) { setBlack(parent); setBlack(uncle); setRed(gparent); node = gparent; continue; } //case2:叔叔节点是黑色,且当前节点是右子节点 if (node == parent.right) { RBNode<T> tmp; leftRotate(parent); tmp = parent; parent = node; node = tmp; } //case3:叔叔节点是黑色,且当前节点是左子节点 setBlack(parent); setRed(gparent); rightRotate(gparent); } else {//父节点是祖父节点的右子节点 RBNode<T> uncle = gparent.left;//叔叔节点 //case1:叔叔节点也是红色 if ((uncle != null) && isRed(uncle)) { setBlack(parent); setBlack(uncle); setRed(gparent); node = gparent; continue; } //case2:叔叔节点是黑色,且当前节点是左子节点 if (node == parent.left) { RBNode<T> tmp; rightRotate(parent); tmp = parent; parent = node; node = tmp; } //case3:叔叔节点是黑色,且当前节点是右子节点 setBlack(parent); setRed(gparent); leftRotate(gparent); } } setBlack(this.root);//将根节点设为黑色 } //左旋 private void leftRotate(RBNode<T> x) { RBNode<T> y = x.right; x.right = y.left; if (y.left != null) { y.left.parent = x; } y.parent = x.parent; if (x.parent == null) { this.root = y; } else { if (x.parent.left == x) { x.parent.left = y; } else { x.parent.right = y; } } y.left = x; x.parent = y; } //右旋 private void rightRotate(RBNode<T> y) { RBNode<T> x = y.left; y.left = x.right; if (x.right != null) { x.right.parent = y; } x.parent = y.parent; if (y.parent == null) { this.root = x; } else { if (y == y.parent.right) { y.parent.right = x; } else { y.parent.left = x; } } x.right = y; y.parent = x; } //获取节点的父节点 private RBNode<T> parentOf(RBNode<T> node) { return node != null ? node.parent : null; } //判断节点是否是红色 private boolean isRed(RBNode<T> node) { return (node != null) && node.color; } //设置节点为红色 private void setRed(RBNode<T> node) { if (node != null) { node.color = true; } } //设置节点为黑色 private void setBlack(RBNode<T> node) { if (node != null) { node.color = false; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值