某高人实现的红黑树模板类

事先声明,这个模板类是我在网上找的(具体在哪找的就忘记了)

红黑树原理请见:http://blog.csdn.net/v_JULY_v/article/details/6105630

实现:

/** 
*  gs_rbtree.h: red-black tree implementation
*
*  a simple c++ template wrapper of linux kernel 2.6.1/rbtree.c
*  Written by Daly.  2009-11
*/

/*
*  Red-black tree reference:
*       http://www.cnblogs.com/abatei/archive/2008/12/17/1356565.html 
*       http://www.cs.princeton.edu/~rs/talks/LLRB/08Penn.pdf
*
*  usage:
*     RbTree<int, struct mytype>  rbt;
*     rbt.insert(12, mytype_object1); 
*     rbt.insert(15, mytype_object2);
*     RbNode<int, struct mytype> *iter = rbt.search(12) //search
*     if (iter != NULL) visit(iter->value);    //get value
*     rbt.erase(12);
*     //alternative: rbt.erase_node(iter); (faster but *iter will become null)
*     iter = rbt.minimum();
* 
*/



#ifndef _GS_RBTREE_H_
#define _GS_RBTREE_H_

#define RB_RED   1
#define RB_BLACK 0

template<typename _KeyType, typename _ValType>
class RbTree;

//red black tree node
template<typename _KeyType, typename _ValType>
class RbNode
{
public:
	_KeyType     key;
	_ValType   value;

private:
	friend class RbTree<_KeyType, _ValType>;
	RbNode<_KeyType, _ValType>  *rb_parent;
	RbNode<_KeyType, _ValType>  *rb_left;
	RbNode<_KeyType, _ValType>  *rb_right;
	int  rb_color;
};



//red-black tree
template<typename _KeyType, typename _ValType>
class RbTree
{
	typedef RbNode<_KeyType, _ValType> NodeLink;
public:
	RbTree() : m_root(NULL) {}
	~RbTree();

	//search node by key. 
	//be careful to use the pointer it return.
	NodeLink* search(_KeyType key) {
		NodeLink *node = m_root;
		while (node) {
			if (key < node->key) 
				node = node->rb_left;
			else if (key > node->key) 
				node = node->rb_right;
			else   //found match
				return node;
		}
		return NULL;
	}

	//insert and fix
	void insert(_KeyType key, _ValType value) {
		NodeLink *node = new NodeLink;
		//fix new leaf
		if (insert_new_node(key, value, node)) {
			insert_fix(node);
		}
	}

	void erase_node(NodeLink *node);
	void erase(_KeyType key);

	NodeLink* minimun()
	{
		NodeLink *p = m_root;
		while (p->rb_left != NULL) 
			p = p->rb_left;
		return p;
	}
	NodeLink* maximum()
	{
		NodeLink *p = m_root;
		while (p->rb_right != NULL) 
			p = p->rb_right;
		return p;
	}

protected:
	bool insert_new_node(_KeyType key, _ValType value, RbTree::NodeLink* node);
	void insert_fix(NodeLink *node);
	void rotate_left(NodeLink *node);
	void rotate_right(NodeLink *node);
	void erase_fixup(NodeLink *node, NodeLink *parent);
	

protected:
	NodeLink *m_root;  //tree root

};

template<typename _KeyType, typename _ValType>
RbTree<_KeyType, _ValType>::~RbTree() 
{
	while (m_root != NULL) 
		erase_node(m_root);
}

/** 
* initialize a new node. just add to the tree's leaf
* @return  false if already exist. true if a new leaf
*/
template<typename _KeyType, typename _ValType>
bool RbTree<_KeyType, _ValType>::insert_new_node(_KeyType key, _ValType value, RbTree::NodeLink* node)
{
	RbNode<_KeyType, _ValType> **pp = &m_root;
	RbNode<_KeyType, _ValType> *parent = NULL;
	RbNode<_KeyType, _ValType> *pnode;
	
	while(*pp) {
		pnode = parent = *pp;
		if (key < pnode->key) {
			pp = &pnode->rb_left;
		}
		else if (key > (*pp)->key) {
			pp = &pnode->rb_right;
		}
		else {   //already exist
			pnode->value = value;
			return false;
		}
	}

	node->rb_parent = parent;
	node->key = key;
	node->value = value;
	node->rb_color = RB_RED;
	node->rb_left = node->rb_right = NULL;
	*pp = node;

	return true;   //a new node

}

template<typename _KeyType, typename _ValType>
void RbTree<_KeyType, _ValType>::rotate_left(RbTree::NodeLink *node)
{
	RbNode<_KeyType, _ValType> *right = node->rb_right;
	
	//update the right's left child and check whether it's null
	if ((node->rb_right = right->rb_left) != NULL) {
		right->rb_left->rb_parent = node;
	}
	right->rb_left = node ;   //become the right's left child
	
	//update parent and check whether it's root
	if ((right->rb_parent = node->rb_parent) != NULL) {
		if (node == node->rb_parent->rb_left)
			node->rb_parent->rb_left = right;
		else
			node->rb_parent->rb_right = right;
	}
	else {
		m_root = right;     //update the root
	}
	node->rb_parent = right;
}

template<typename _KeyType, typename _ValType>
void RbTree<_KeyType, _ValType>::rotate_right(RbTree::NodeLink *node)
{
	RbNode<_KeyType, _ValType> *left = node->rb_left;

	if ((node->rb_left = left->rb_right) != NULL) {
		left->rb_right->rb_parent = node;
	}
	left->rb_right = node;

	if ((left->rb_parent = node->rb_parent) != NULL) {
		if (node == node->rb_parent->rb_right)
			node->rb_parent->rb_right = left;
		else
			node->rb_parent->rb_left = left;
	}
	else {
		m_root = left;
	}
	node->rb_parent = left;
}



template<typename _KeyType, typename _ValType>
void RbTree<_KeyType, _ValType>::insert_fix(RbTree::NodeLink *node)
{
	RbNode<_KeyType, _ValType> *parent, *grandparent, *uncle, *tmp;
	
	//fix if two consecutive red node
	while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
	{
		grandparent = parent->rb_parent;    //grandparent sure to be not null
		//begin left-branch case
		if (parent == grandparent->rb_left) {
			uncle = grandparent->rb_right;
			//parent and uncle are both red
			if (uncle && uncle->rb_color == RB_RED) {
				uncle->rb_color = RB_BLACK;       //color flip
				parent->rb_color = RB_BLACK;
				grandparent->rb_color = RB_RED;
				node = grandparent;
				continue;     //up to the root
			}
			//black uncle
			if (parent->rb_right == node) {
				rotate_left(parent);       //left-leaning 
				tmp = parent;     //update pointers after rotation
				parent = node;
				node = tmp;
			}
			parent->rb_color = RB_BLACK;     //color update before rotation
			grandparent->rb_color = RB_RED;
			rotate_right(grandparent);
		}
		else {  //begin right branch case
			uncle = grandparent->rb_left;
			if (uncle && uncle->rb_color == RB_RED) {
				uncle->rb_color = RB_BLACK;
				parent->rb_color = RB_BLACK;
				grandparent->rb_color = RB_RED;
				node = grandparent;
				continue;
			}

			if (parent->rb_left == node) {
				rotate_right(parent);
				tmp = parent;
				parent = node;
				node = tmp;
			}
			parent->rb_color = RB_BLACK;
			grandparent->rb_color = RB_RED;
			rotate_left(grandparent);
		}
	}

	m_root->rb_color = RB_BLACK;    //root should be black
}

template<typename _KeyType, typename _ValType>
void RbTree<_KeyType, _ValType>::erase(_KeyType key)
{
	RbNode<_KeyType, _ValType> *node = search(key);
	erase_node(node);
}

template<typename _KeyType, typename _ValType>
void RbTree<_KeyType,_ValType>::erase_node(RbTree::NodeLink *node)
{
	RbNode<_KeyType, _ValType> *child, *parent;
	int color;
	if (node == NULL) return;

	if (!node->rb_left)         //right single link or leaf
		child = node->rb_right;
	else if (!node->rb_right)   //left single link
		child = node->rb_left;
	else  //internal node
	{
		NodeLink *old = node, *left;
		node = node->rb_right;
		//find successor
		while ((left = node->rb_left) != NULL) {
			node = left;
		}
		child = node->rb_right;   //succesor's child
		parent = node->rb_parent;
		color = node->rb_color;
		//update link
		if (child)
			child->rb_parent = parent;
		if (parent) {
			if (parent->rb_left == node)
				parent->rb_left = child;
			else 
				parent->rb_right = child;
		}
		else {  //delete root
			m_root = child;
		}

		if (node->rb_parent == old) {
			parent = node;
		}
		//succussor replace the node to be deleted
		node->rb_parent = old->rb_parent;
		node->rb_color = old->rb_color;
		node->rb_right = old->rb_right;
		node->rb_left = old->rb_left;

		if (old->rb_parent) {
			if (old->rb_parent->rb_left == old)
				old->rb_parent->rb_left = node;
			else
				old->rb_parent->rb_right = node;
		}
		else {
			m_root = node;
		}

		old->rb_left->rb_parent = node;
		if (old->rb_right) {
			old->rb_right->rb_parent = node;
		}
		delete old;     //release memory
		goto fixup_color;   //jump to fix-up
	}

	//handle single link case or leaf
	parent = node->rb_parent;
	color = node->rb_color;

	if (child)
		child->rb_parent = parent;
	if (parent)
	{
		if (parent->rb_left == node)
			parent->rb_left = child;
		else
			parent->rb_right = child;
	}
	else {
		m_root = child;
	}
	delete node;

fixup_color:
	if (color == RB_BLACK) {
		erase_fixup(child, parent);
	}
}

template<typename _KeyType, typename _ValType>
void RbTree<_KeyType, _ValType>::erase_fixup(RbTree::NodeLink *node, RbTree::NodeLink *parent)
{
	RbNode<_KeyType, _ValType> *other;
	//only to fix black child
	while ((!node || node->rb_color == RB_BLACK) && node != m_root)
	{
		//handle left-branch case
		if (parent->rb_left == node)
		{
			other = parent->rb_right;
			if (other->rb_color == RB_RED) {   //red brother. just flip color
				other->rb_color = RB_BLACK;
				parent->rb_color = RB_RED;
			    rotate_left(parent);
				other = parent->rb_right;     //go down a level after rotation and go on fixing up
			}
			//black brother case and two black nephew
			if ((!other->rb_left ||
				other->rb_left->rb_color == RB_BLACK) &&    
				(!other->rb_right || 
				    other->rb_right->rb_color == RB_BLACK))
			{
				other->rb_color = RB_RED;
				node = parent;               //go up
				parent = node->rb_parent;
	
			}
			else  //less than two black nephew
			{
				//there's one black nephew
				if (!other->rb_right ||
					other->rb_right->rb_color == RB_BLACK)
				{
					RbNode<_KeyType, _ValType> *o_left;
					if ((o_left = other->rb_left) != NULL) {
						o_left->rb_color = RB_BLACK;
					}
					other->rb_color = RB_RED;
					rotate_right(other);
					other = parent->rb_right;
				}
				other->rb_color = parent->rb_color;
				parent->rb_color = RB_BLACK;
				if (other->rb_right)
					other->rb_right->rb_color = RB_BLACK;
				rotate_left(parent);
				node = m_root;
				break;    //finish
			}
		}
		else   //right case. symmetry code
		{
			other = parent->rb_left;
			if (other->rb_color == RB_RED)
			{
				other->rb_color = RB_BLACK;
				parent->rb_color = RB_RED;
				rotate_right(parent);
				other = parent->rb_left;
			}
			if ((!other->rb_left ||
				other->rb_left->rb_color == RB_BLACK)
				&& (!other->rb_right ||
				    other->rb_right->rb_color == RB_BLACK))
			{
				other->rb_color = RB_RED;
				node = parent;
				parent = node->rb_parent;
			}
			else
			{
				if (!other->rb_left ||
					other->rb_left->rb_color ==  RB_BLACK)
				{
					RbNode<_KeyType, _ValType> *o_right;
					if ((o_right = other->rb_right) != NULL) {
						o_right->rb_color = RB_BLACK;
					}
					other->rb_color = RB_RED;
					rotate_left(other);
					other = parent->rb_left;
				}
				other->rb_color = parent->rb_color;
				parent->rb_color = RB_BLACK;
				if (other->rb_left) {
					other->rb_left->rb_color = RB_BLACK;
				}
				rotate_right(parent);
				node = m_root;
				break;
			}
		}
	}//end loop
	
	if (node != NULL) {
		node->rb_color = RB_BLACK;
	}
}

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值