如果你学习过了AVL树,那么RBTree你也会学的很快,如果你没有,你可以看看这篇博客:
http://blog.youkuaiyun.com/fengasdfgh/article/details/52917527
AVL树是一个比较严格的平衡搜索二叉树,它搜索一个数的时间复杂度为o(lgN),然而维护它的代价却显的高昂。
相信大家都对AVL树的平衡因子感到烦躁,这就是红黑树出现的原因,它比AVL树更容易维护,理解,学习。它搜索一个数的时间复杂度近似为
o(lgN)。
下面是红黑树的基本性质:
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
除了以上的性质,在有的书上或者你听别人说还有第5个性质:
- 每个叶子节点都是黑色的。
请注意这里的叶子节点是指的NULL节点。这个性质可有可无,它的出现只是为了完善其他性质。
和AVL树一样,我们重点分析它的节点插入操作,至于删除和其他操作,只要学会了插入操作,其他的也能自己推导。
当新节点找到插入的位置时,如果父节点father的颜色为黑,则直接插入,为红时则需要进行操作。
大致分为三种情况:
1.uncle存在且为红
我们只需把father与uncle的颜色变为黑,grandfather的颜色变为红,然后继续向上调整(这是一个递归的过程),因为
grandfather的颜色发生改变,这可能会影响到祖父节点的颜色。
但是有特殊情况:
如果grandfather为根节点,则我们只把father和uncle变为黑色。
2.uncle不存在或为黑(统一视uncle为黑色)
father为grandfather的左节点,child为father的左节点
father为grandfather的右节点,child为father的右节点
我们只需要进行一次右/左旋转,旋转轴点为grandfather。并且再把grandfather的颜色变为红,father的颜色变为黑
3uncle不存在或颜色为黑(统一视uncle为黑色)
我们只需要把这种情况转为情况2即可,需要进行一次右/左旋转,旋转轴点为father。
在写完这些后,你可以写个判断函数看你是否调整正确:
bool ISblance()
{
Node *cur = _root;
int stand = 0;
while (cur != NULL)
{
if (cur->_colour == BLACK)
stand++;
cur = cur->_left;
}
return ISblance(_root, 0, stand);
}
bool ISblance(Node *root, int count, const int stand)
{
if (NULL == root)
return true;
if (root->_colour == BLACK)
{
count++;
}
else if (root->_father && root->_father->_colour == RED)
{
cout << "2个红节点" << root->_key << endl;
return false;
}
if ((NULL == root->_left || NULL == root->_right)&&count != stand)
{
cout << "路径黑节点不相等:" << root->_key << endl;
return false;
}
ISblance(root->_left, count, stand);
ISblance(root->_right, count, stand);
return true;
}
代码如下(只实现了插入):
#pragma once
#include <iostream>
using namespace std;
enum
{
RED,
BLACK,
};
template<typename K , typename T = int>
struct RBTreeNode
{
typedef RBTreeNode<K, T> Node;
RBTreeNode(const K& key, const T& value= T())
:_key(key)
,_value(value)
,_left(NULL)
,_right(NULL)
,_father(NULL)
,_colour(RED)
{
}
const K _key;
T _value;
int _colour;
Node *_left;
Node *_right;
Node *_father;
};
template<class K, class T = int>
class RBTree
{
public:
typedef RBTreeNode<K, T> Node;
typedef RBTree<K, T> tree;
RBTree()
:_root(NULL)
{
};
bool insert(const K& key, const T& value = T())
{
Node *p = new Node(key, value);
if (NULL == _root)
{
_root = p;
p->_colour = BLACK;
return true;
}
//找到要插入的位置
Node *cur = _root;
Node *father = NULL;
while (NULL != cur)
{
father = cur;
if (cur->_key == key)
{
delete p;
return false;
}
else
{
if (cur->_key < key)
cur = cur->_right;
else cur = cur->_left;
}
}
if (key > father->_key)
father->_right = p;
else father->_left = p;
p->_father = father;
adjust(p, father);
ISblance();
}
void middle_play()
{
middle_play(_root);
}
protected:
void middle_play(Node *root)
{
if (NULL == root)
return;
middle_play(root->_left);
cout << root->_key << endl;
middle_play(root->_right);
}
//左旋
void rotate_left(Node *father)
{
Node *grandfather = father->_father;
Node *great_father = grandfather->_father;
grandfather->_right = father->_left;
if (NULL != father->_left)
father->_left->_father = grandfather;
father->_left = grandfather;
grandfather->_father = father;
if (NULL != great_father)
{
if (great_father->_left == grandfather)
great_father->_left = father;
else great_father->_right = father;
}
else _root = father;
father->_father = great_father;
}
//右旋
void rotate_right(Node *father)
{
Node *grandfather = father->_father;
Node *great_father = grandfather->_father;
grandfather->_left = father->_right;
if (NULL != father->_right)
father->_right->_father = grandfather;
father->_right = grandfather;
grandfather->_father = father;
if (NULL != great_father)
{
if (great_father->_left == grandfather)
great_father->_left = father;
else great_father->_right = father;
}
else _root = father;
father->_father = great_father;
}
//左右旋
Node *rotate_left_right(Node *father)
{
father = father->_right;
rotate_left(father);
rotate_right(father);
}
//右左旋
Node *rotate_right_left(Node *father)
{
father = father->_left;
rotate_right(father);
rotate_left(father);
}
void adjust(Node *child, Node *father)
{
if (BLACK == father->_colour)
return;
Node *grandfather = father->_father;
Node *uncle = NULL;
if (father == grandfather->_left)
uncle = grandfather->_right;
else uncle = grandfather->_left;
if (NULL == uncle || uncle->_colour == BLACK)
{
if (father == grandfather->_left)
{
if (father->_right == child)
{
rotate_left(child);
father = child;
}
rotate_right(father);
father->_colour = BLACK;
grandfather->_colour = RED;
}
else
{
if (father->_left == child)
{
rotate_right(child);
father = child;
}
rotate_left(father);
father->_colour = BLACK;
grandfather->_colour = RED;
}
}
else
{
father->_colour = BLACK;
uncle->_colour = BLACK;
if (grandfather->_father != NULL)
{
grandfather->_colour = RED;
adjust(grandfather, grandfather->_father);
}
}
}
bool ISblance()
{
Node *cur = _root;
int stand = 0;
while (cur != NULL)
{
if (cur->_colour == BLACK)
stand++;
cur = cur->_left;
}
return ISblance(_root, 0, stand);
}
bool ISblance(Node *root, int count, const int stand)
{
if (NULL == root)
return true;
if (root->_colour == BLACK)
{
count++;
}
else if (root->_father && root->_father->_colour == RED)
{
cout << "2个红节点" << root->_key << endl;
return false;
}
if ((NULL == root->_left || NULL == root->_right)&&count != stand)
{
cout << "路径黑节点不相等:" << root->_key << endl;
return false;
}
ISblance(root->_left, count, stand);
ISblance(root->_right, count, stand);
return true;
}
private:
Node *_root;
};