一、红黑树
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示结点的颜色,可以是 red 或者 black ,通过对任何一条从根节点到叶子节点简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似平衡,而且在实际应用中发现红黑树性能确实比 AVL 树 性能高。
AVL树实现代码: https://blog.csdn.net/lz201788/article/details/79451815
二、性质
1.每个节点不是红色就是黑色
2.树的根节点是黑色的
3.如果一个节点是红色的,则它的两个孩子节点是黑色的(没有两个连续的红色节点)
4.对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点(每条路径上黑色节点的数量相等)
三、插入实现
【情况一】
若树为空,插入后违反性质2,需要将新增节点改成黑色。
【情况二】
插入节点的父亲节点为黑色,不违反任何性质,直接插入。
约定:cur为当前节点,p为父亲节点,g为祖父节点,u为叔叔节点
【情况三】
【情况四】
【情况五】
【代码实现】
【RBTree.h】
#pragma once
#include<iostream>
using namespace std;
enum Color
{
RED,
BLACK
};
template<class K,class V>
struct RBNode
{
RBNode()
:_Lchild(NULL)
,_Rchild(NULL)
,_Parent(NULL)
, _color(RED)
{ }
RBNode(K key,V value,Color color=RED)
:_Lchild(NULL)
, _Rchild(NULL)
, _Parent(NULL)
, _key(key)
, _value(value)
, _color(color)
{ }
RBNode<K, V>* _Lchild;
RBNode<K, V>* _Rchild;
RBNode<K, V>* _Parent;
K _key;
V _value;
Color _color;
};
template<class K, class V>
class RBTree
{
typedef RBNode<K, V> Node;
typedef RBNode<K, V>* pNode;
public:
RBTree()
{
Root = NULL;
}
bool Insert(K k,V v)
{
return _Insert(Root,k,v);
}
void InOrder()
{
_InOrder(Root);
}
bool CheckRBT()
{
int blackcount = 0;
int k = 0;
pNode cur = Root;
while (cur)
{
if (cur->_color == BLACK)
blackcount++;
cur = cur->_Lchild;
}
return _CheckRBT(Root,blackcount,k);
}
private:
bool _CheckRBT(pNode pRoot,int blackcount,int k)
{
if (pRoot == NULL)
{
if (blackcount == k)
return true;
else
return false;
}
if (pRoot->_color == RED&&pRoot->_Parent->_color == RED)
return false;
if (pRoot->_color == BLACK)
k++;
return _CheckRBT(pRoot->_Lchild,blackcount,k);
return _CheckRBT(pRoot->_Rchild, blackcount, k);
}
void _InOrder(pNode pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_Lchild);
cout << "<" << pRoot->_key << "," << pRoot->_value << ">" << endl;
_InOrder(pRoot->_Rchild);
}
}
bool _Insert(pNode& pRoot,K k,V v)
{
pNode newNode = new Node(k, v);
if (pRoot == NULL) //情况一
{
pRoot = newNode;
newNode->_color = BLACK;
}
pNode cur = pRoot;
pNode pParent = NULL;
while (cur)
{ //查找要插入的位置
pParent = cur;
if (cur->_key > k)
cur = cur->_Lchild;
else if (cur->_key < k)
cur = cur->_Rchild;
else
return false; //k已存在
}
if (pParent->_key>k)
{
pParent->_Lchild = newNode;
newNode->_Parent = pParent;
}
else
{
pParent->_Rchild = newNode;
newNode->_Parent = pParent;
}
cur = newNode;
pNode u = NULL;
pNode p = pParent;
while (cur!=Root&&p->_color==RED)
{
pNode g = p->_Parent;
if (p== g->_Lchild)
u = g->_Rchild;
else
u = g->_Lchild;
if (p->_color == BLACK) //情况二
return true;
else if (cur->_color==RED&&u->_color==RED) //情况三
{
p->_color = BLACK;
u->_color = BLACK;
if (g!=Root)
g->_color = RED;
cur = g;
p = cur->_Parent;
}
else if (cur->_color == RED&&g->_color == BLACK&&(u->_color==BLACK||u==NULL)) //情况四
{
p->_color = BLACK;
g->_color = RED;
if (cur == p->_Lchild&&p == g->_Lchild)
{
//右单旋
RotateRight(g);
}
else if (cur == p->_Rchild&&p == g->_Rchild)
{
//左单旋
RotateLeft(g);
}
}
else if (cur->_color == RED&&g->_color == BLACK && (u->_color == BLACK || u == NULL))
{
if (p == g->_Lchild&&cur == p->_Rchild)
{
//左单旋
RotateLeft(p);
swap(cur, p);
}
else if (p == g->_Rchild&&cur == p->_Lchild)
{
//右单旋
RotateRight(p);
swap(cur, p);
}
}
if (g == Root)
g->_color = BLACK;
}
return true;
}
void RotateLeft(pNode g)
{
pNode pSubR = g->_Rchild;
pNode pSubRL = pSubR->_Lchild;
pNode pParent = g->_Parent;
g->_Rchild = pSubRL;
if (pSubRL != NULL)
pSubRL->_Parent = g;
pSubR->_Lchild = g;
g->_Parent = pSubR;
if (pParent == NULL)
Root = pSubR;
else if (pParent != NULL&&g == pParent->_Lchild)
{
pParent->_Lchild = g;
g->_Parent = pParent;
}
else if (pParent != NULL&&g == pParent->_Rchild)
{
pParent->_Rchild = g;
g->_Parent = pParent;
}
}
void RotateRight(pNode g)
{
pNode pSubL = g->_Lchild;
pNode pSubLR = pSubL->_Rchild;
pNode pParent = g->_Parent;
g->_Lchild = pSubLR;
if (pSubLR)
pSubLR->_Parent = g;
pSubL->_Rchild = g;
g->_Parent = pSubL;
if (pParent == NULL)
Root = pSubL;
else if (pParent != NULL&&g == pParent->_Lchild)
{
pParent->_Lchild = pSubL;
pSubL->_Parent = pParent;
}
else if (pParent != NULL&&g == pParent->_Rchild)
{
pParent->_Rchild = pSubL;
pSubL->_Parent = pParent;
}
}
private:
pNode Root;
};
//【测试函数】
void Test()
{
RBTree<int, int> t;
int arr[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size; i++)
{
t.Insert(arr[i], i);
}
t.InOrder();
if (t.CheckRBT() == true)
cout << "是红黑树" << endl;
else
cout << "不是红黑树" << endl;
}
【test.cpp】
#include"RBTree.h"
int main()
{
Test();
system("pause");
return 0;
}
【删除】:(参考下面的博客)
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html
https://blog.csdn.net/chenhuajie123/article/details/11951777