C++实现红黑树

一. 红黑树的概念:

       红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结 点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点简 单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而 近似平衡,而且在实际应用中发现红黑树性能确实比AVL树性能高。

二. 红黑树的性质:

1. 每个结点不是红色就是黑色; 

2. 树的根节点是黑色的 ;

3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(没有两个连续的 红色结点) ;

4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相 同数目的黑色结点(每条路径上黑色结点的数量相等);

5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点;

三. 插入实现情况:

【情况一】 若树为空,插入后违反性质2 ,需将新增结点改成黑色。

【情况二】 插入结点的父节点为黑色,不违反任何性质,直接插入。

【情况三】 cur为红,p为红,g为黑,u存在且为红。

C++实现红黑树_第1张图片

【情况四】 cur为红,p为红,g为黑,u不存在/u为黑。

C++实现红黑树_第2张图片

【情况五】 cur为红,p为红,g为黑,u不存在/u为黑 。

C++实现红黑树_第3张图片

四. 实现代码:

#include
using namespace std;

enum COLOR{RED,BLACK};

template
struct RBTreeNode{
	RBTreeNode* _pLeft;
	RBTreeNode* _pRight;
	RBTreeNode* _pParent;
	pair _value;
	COLOR _color;
	RBTreeNode(const K& key, const V& value, COLOR color = RED)
		: _pLeft(NULL)
		, _pRight(NULL)
		, _pParent(NULL)
		, _value(key,value)
		, _color(color)
	{}
};

template
class RBTree{
	typedef RBTreeNode Node;
	typedef Node* PNode;
public:
	RBTree()
		:_pRoot(NULL)
	{}
	bool InsertUnique(const pair value)
	{
		if (NULL == _pRoot){
			_pRoot = new Node(value.first, value.second, BLACK);
			return true;
		}
		PNode pCur = _pRoot;
		PNode pParent = pCur;
		while (pCur){
			if (pCur->_value.first < value.first){
				pParent = pCur;
				pCur = pCur->_pRight;
			}
			else if (pCur->_value.first>value.first){
				pParent = pCur;
				pCur = pCur->_pLeft;
			}
			else
				return false;
		}
		pCur = new Node(value.first, value.second);
		if (value.first < pParent->_value.first)
			pParent->_pLeft = pCur;
		else
			pParent->_pRight = pCur;
		pCur->_pParent = pParent;
		while (pParent&& pParent->_color == RED){
			PNode grandParent = pParent->_pParent;
			if (pParent == grandParent->_pLeft){
				PNode pUncle = grandParent->_pRight;
				if (pUncle&&pUncle->_color == RED){
					pParent->_color = BLACK;
					pUncle->_color = BLACK;
					grandParent->_color = RED;
					grandParent = pCur;
					pParent = pCur->_pParent;
				}
				else {
					if (pCur == pParent->_pRight){
						rotateL(pParent);
						swap(pCur, pParent);
					}
					grandParent->_color = RED;
					pParent->_color = BLACK;
					rotateR(grandParent);
				}
			}
			else{
				PNode pUncle = grandParent->_pLeft;
				if (pUncle&&pUncle->_color == RED){
					pParent->_color = BLACK;
					pUncle->_color = BLACK;
					grandParent->_color = RED;
					grandParent = pCur;
					pParent = pCur->_pParent;
				}
				else {
					if (pCur == pParent->_pLeft){
						rotateR(pParent);
						swap(pCur, pParent);
					}
					grandParent->_color = RED;
					pParent->_color = BLACK;
					rotateL(grandParent);
				}
			}
		}
		_pRoot->_color = BLACK;
		return true;
	}
	void InOrder()
	{
		cout << "InOrder:";
		_InOrder(_pRoot);
		cout << endl;
	}
	bool IsRBTree()
	{
		if (NULL == _pRoot)
			return true;
		if (RED == _pRoot->_color){
			cout << "根节点为红色违反性质2" << endl;
			return false;
		}
		// 统计单条路径中黑色结点的个数
		size_t blackCount = 0;
		PNode pCur = _pRoot;
		while (pCur){
			if (BLACK == pCur->_color)
				++blackCount;
			pCur = pCur->_pLeft;
                }		
		size_t pathCount = 0;
		return _IsRBTree(_pRoot, pathCount, blackCount);
	}
private:
	void rotateL(PNode pParent)
	{
		PNode pSubR = pParent->_pRight;
		PNode pSubRL = pSubR->_pLeft;
		pParent->_pRight = pSubRL;
		if (pSubRL)
			pSubRL->_pParent = pParent;
		pSubR->_pLeft = pParent;
		PNode pPParent = pParent->_pParent;
		pParent->_pParent = pSubR;
		pSubR->_pParent = pPParent;
		if (NULL == pPParent){
			_pRoot = pSubR;
			pSubR->_pParent = NULL;
		}
		else{
			if (pPParent->_pLeft == pParent)
				pPParent->_pLeft = pSubR;
			else
				pPParent->_pRight = pSubR;
		}
	}
	void rotateR(PNode pParent)
	{
		PNode pSubL = pParent->_pLeft;
		PNode pSubLR = pSubL->_pRight;
		pParent->_pLeft = pSubLR;
		if (pSubLR)
			pSubLR->_pParent = pParent;
		pSubL->_pRight = pParent;
		PNode pPParent = pParent->_pParent;
		pParent->_pParent = pSubL;
		pSubL->_pParent = pPParent;
		if (NULL == pPParent){
			_pRoot = pSubL;
			pSubL->_pParent = NULL;
		}
		else{
			if (pPParent->_pLeft == pParent)
				pPParent->_pLeft = pSubL;
			else
				pPParent->_pRight = pSubL;
		}
	}
	void _InOrder(PNode pRoot)
	{
		if (pRoot){
			_InOrder(pRoot->_pLeft);
			cout << "<" << pRoot->_value.first << "," << pRoot->_value.second << ">";
			_InOrder(pRoot->_pRight);
		}
	}

	bool _IsRBTree(PNode pRoot, size_t n, size_t blackCount)
	{
		if (NULL == pRoot)
			return true;
		if (BLACK == pRoot->_color)
			++n;
		PNode pParent = pRoot->_pParent;
		if (pParent && RED == pRoot->_color && RED == pParent->_color){
			cout << "有连在一起的红色结点违反性质3" << endl;
			return false;
		}
		if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight){
			if (n != blackCount){
				cout << "路径中黑色结点个数不同违反性质4" << endl;
				return false;
			}
		}
		return _IsRBTree(pRoot->_pLeft, n, blackCount) && _IsRBTree(pRoot->_pRight, n, blackCount);
	}
private:
	PNode _pRoot;
};

template
class __RBTreeiterator__
{
	typedef RBTreeNode Node;
	typedef Node* PNode;
	typedef __RBTreeiterator__ Self;

public:
	__RBTreeiterator__(PNode pNode = NULL)
		: _pNode(pNode)
	{}

	__RBTreeiterator__(const Self& s)
		: _pNode(s._pNode)
	{}

	pair& operator*()
	{
		return _pNode->_value;
	}

	pair* operator->()
	{
		return &(operator*());
	}

	Self& operator++()
	{
		RBTreeItIncrement();
		return *this;
	}

	Self operator++(int)
	{
		Self temp(*this);
		RBTreeItIncrement();
		return temp;
	}

	Self& operator--()
	{
		RBTreeItDecrement();
		return *this;
	}

	Self operator--(int)
	{
		Self temp(*this);
		RBTreeItDecrement();
		return temp;
	}

	bool operator==(const Self& s)
	{
		return _pNode == s._pNode;
	}

	bool operator!=(const Self& s)
	{
		return _pNode != s._pNode;
	}

private:
	void RBTreeItIncrement()
	{
		if (_pNode->_pRight)
		{
			_pNode = _pNode->_pRight;
			while (_pNode->_pLeft)
				_pNode = _pNode->_pLeft;
		}
		else
		{
			PNode pParent = _pNode->_pParent;
			while (pParent->_pRight == _pNode)
			{
				_pNode = pParent;
				pParent = _pNode->_pParent;
			}

			// 如果树的根节点没有右孩子的情况且迭代器起始位置在根节点
			if (_pNode->_pRight != pParent)
				_pNode = pParent;
		}
	}

	void RBTreeItDecrement()
	{
		if (_pNode->_pParent->_pParent == _pNode && RED == _pNode->_color)
		{
			_pNode = _pNode->_pRight;
		}
		else if (_pNode->_pLeft)
		{
			// 在当前节点左子树中找最大的结点
			_pNode = _pNode->_pLeft;
			while (_pNode->_pRight)
				_pNode = _pNode->_pRight;
		}
		else
		{
			PNode pParent = _pNode;
			while (pParent->_pLeft == _pNode)
			{
				_pNode = pParent;
				pParent = _pNode->_pParent;
			}

			_pNode = pParent;
		}
	}

private:
	PNode _pNode;
};


void test(){
	int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
	RBTree rt;
	for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
		rt.InsertUnique(pair(a[i],i));
	rt.InOrder();
	if (rt.IsRBTree())
		cout << "是红黑树" << endl;
	else
		cout << "不是红黑树" << endl;
}

int main(){
	test();
	return 0;
}

结果截图:

C++实现红黑树_第4张图片

你可能感兴趣的:(C++实现红黑树)