一、紅黑樹
紅黑樹是一棵二叉搜索樹,它在每個節點上增加了一個存儲位來表示結點的顏色,可以是 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