红黑树特性:
1、节点颜色非黑即红
2、根节点颜色一定是黑色
3、某一节点到其任意叶节点的路径中黑结点数量相等(保证了这颗树最长路径长度不超过最短路径的2倍)
4、不能有连续的两个红节点
#ifndef __RBTREE__
#define __RBTREE__
#include <iostream>
#include <stack>
//节点颜色,非黑即红
enum colour{
RED,
BLACK
};
//节点数据结构
template<class K>
struct RBTreeNode
{
typedef RBTreeNode<K>* Node_p;
Node_p _left;
Node_p _right;
Node_p _parent;
K _key;
colour _colour;
RBTreeNode(const K& key = K())
:_left(NULL)
, _right(NULL)
, _parent(NULL)
, _key(key)
, _colour(RED)
{}
};
//红黑树结构
template<class K>
class RBTree
{
typedef RBTreeNode<K> Node;
typedef Node* Node_p;
public:
RBTree()
:_root(NULL)
{}
std::pair<Node_p, bool> Find(K key)
{
if (_root == NULL){
return std::pair<Node_p, bool>(NULL, false);
}
Node_p cur = _root;
Node_p parent = NULL;
while (cur){
if (cur->_key == key)
return std::pair<Node_p, bool>(cur, true);
else if (key < cur->_key){
parent = cur;
cur = cur->_left;
}
else{
parent = cur;
cur = cur->_right;
}
}
return std::pair<Node_p, bool>(parent, false);
}
bool Insert(K key)
{
if (_root == NULL){//空树
_root = new Node(key);
_root->_colour = BLACK;
return true;
}
std::pair<Node_p, bool> ret = Find(key);
if (ret.second)//找到了键为key的节点,无法插入
return false;
Node_p parent = ret.first;
Node_p Grandparent = parent->_parent;
Node_p cur;
Node_p GGrandparent;
_Insert(parent,key);
if (parent->_colour == BLACK)
return true;
//祖父节点Grandparent一定存在
if (key < parent->_key){
cur = parent->_left;
}
else{
cur = parent->_right;
}
//***********************以上插入成功
//***********************以下判断是否需要旋转变色
Node_p Uncle;
while (Grandparent){
if (parent == Grandparent->_left)
Uncle = Grandparent->_right;
else
Uncle = Grandparent->_left;
GGrandparent = Grandparent->_parent;
if (Uncle == NULL || Uncle->_colour == BLACK){//Grandparent一定为黑,旋转之后也一定为黑
if (parent == Grandparent->_left){
if (parent->_right == cur){//U为黑,cur内插,把cur转换为外插
_RotateL(parent);
std::swap(parent,cur);
}
_RotateR(Grandparent);
parent->_colour = BLACK;
Grandparent->_colour = RED;
}
else{
if (parent->_left == cur){//U为黑,cur内插,把cur转换为外插
_RotateR(parent);
std::swap(parent, cur);
}
_RotateL(Grandparent);
parent->_colour = BLACK;
Grandparent->_colour = RED;
}
break;
}
else if (Uncle->_colour == RED){//Grandparent一定为黑,旋转之后为红
if (parent == Grandparent->_left){
if (parent->_right == cur){//U为红,cur内插,转为外插
_RotateL(parent);
std::swap(parent, cur);
}
_RotateR(Grandparent);
cur->_colour = BLACK;
}
else{
if (parent-> _left == cur){//U为红,cur内插
_RotateR(parent);
std::swap(parent, cur);
}
_RotateL(Grandparent);
cur->_colour = BLACK;
}
if (GGrandparent && GGrandparent->_colour == RED){
cur = parent ;
parent = cur->_parent;
Grandparent = parent->_parent;
}
else
break;
}
}
_root->_colour = BLACK;
return true;
}
void InOrder()
{
_InOrder(_root);
std::cout << std::endl;
}
void InOrder_Non_R()
{
std::stack<Node_p> s;
Node_p cur = _root;
while (cur || !s.empty() ){
while (cur){
s.push(cur);
cur = cur->_left;
}
Node_p tmp=s.top();
s.pop();
std::cout << tmp->_key<<" ";
cur = tmp->_right;
}
std::cout << std::endl;
}
bool Is_Balance()
{}
private:
void _Insert(Node_p cur,K& key)
{
Node_p tmp = new Node(key);
if (key < cur->_key){
cur->_left = tmp;
}
else{
cur->_right = tmp;
}
tmp->_parent = cur;
}
//左旋
void _RotateL(Node_p parent)
{
Node_p subR = parent->_right;
Node_p subRL = subR->_left;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
subR->_left = parent;
Node_p ppNode = parent->_parent;
parent->_parent = subR;
if (ppNode){
if (ppNode->_left == parent)
ppNode->_left = subR;
else
ppNode->_right = subR;
subR->_parent = ppNode;
}
else{
_root = subR;
subR->_parent = NULL;
}
}
//右旋
void _RotateR(Node_p parent)
{
Node_p subL = parent->_left;
Node_p subLR = subL->_right;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
Node_p ppNode = parent->_parent;
subL->_right = parent;
parent->_parent = subL;
if (ppNode){
if (ppNode->_left == parent)
ppNode->_left = subL;
else
ppNode->_right = subL;
subL->_parent = ppNode;
}
else{
_root = subL;
subL->_parent = NULL;
}
}
void _InOrder(Node_p root)
{
if (root == NULL)
return;
_InOrder(root->_left);
std::cout << root->_key << " ";
_InOrder(root->_right);
}
protected:
Node_p _root;
size_t _node_count;//记录结点数量
};
#endif
转载于:https://blog.51cto.com/lingdandan/1837331