红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。
写红黑树只需要了解以下性质
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
<span style="font-size:18px;">#include "stdafx.h"
#include<deque>
#include<iostream>
#define KeyType int
#define MAX -1000000
#define MIN 1000000
/*性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。*/
class RBTree
{
public:
const static enum Color{
red, black
};
const static struct RBNode
{
Color color;
KeyType ele;
RBNode*lnode, *rnode, *parent;
};
private:
RBNode*root;
RBNode* findnode(const KeyType val);
RBNode*findminmax(const KeyType val);
void destroy();
void inorder(RBNode*node);
void insert_adjust(RBNode*node);
bool isfullblack(RBNode*node);
public:
RBTree()
{
root = NULL;
}
bool insert(const KeyType val);
bool erase(const KeyType val);
bool find(const KeyType val){ return findnode(val) != NULL; }
RBNode*getRoot();//测试用
~RBTree()
{
destroy();
}
};
std::deque<RBTree::RBNode*>aa;
void RBTree::inorder(RBTree::RBNode*nn)
{
if (nn == NULL)
return;
inorder(nn->lnode);
aa.push_back(nn);
inorder(nn->rnode);
}
RBTree::RBNode*RBTree::getRoot()
{
return root;
}
RBTree::RBNode*RBTree::findnode(const KeyType val)
{
if (root == NULL)
return NULL;
RBNode*nn = root;
while (nn != NULL)
{
if (nn->ele == val)
return nn;
if (nn->ele > val)
nn = nn->lnode;
else
nn = nn->rnode;
}
return NULL;
}
RBTree::RBNode*RBTree::findminmax(const KeyType val)//找到插入节点的位置
{
_ASSERTE(val > MAX&&val < MIN);
std::deque<RBNode*>aa;
aa.push_back(root);
RBNode*minmax = NULL;
int near = MIN;
while (!aa.empty())//非递归先根遍历
{
RBNode*node = aa.back();
aa.pop_back();
if (node->ele - val > 0 && node->ele - val < near)
{
minmax = node;
near = node->ele - val;
}
if (node->rnode != NULL)
aa.push_back(node->rnode);
if (node->lnode != NULL)
aa.push_back(node->lnode);
}
return minmax;
}
void RBTree::destroy()
{
if (root == NULL)
return;
std::deque<RBNode*>aa, bb;
aa.push_back(root);
while (!aa.empty())//非递归先根遍历
{
RBNode*node = aa.back();
aa.pop_back();
bb.push_back(node);
if (node->rnode != NULL)
aa.push_back(node->rnode);
if (node->lnode != NULL)
aa.push_back(node->lnode);
}
for (int i = 0; i < bb.size(); i++)
{
delete bb[i];
}
}
void RBTree::insert_adjust(RBTree::RBNode*node)
{
while (node->parent != NULL)
{
if (node->parent->color == black)
{
return;
}
RBNode*parent = node->parent;
RBNode*grandpa = node->parent->parent;
if (parent->rnode == node&&grandpa->lnode == parent)
{
RBNode*node_lnode = node->lnode;
RBNode*node_rnode = node->rnode;
RBNode*gg = grandpa->parent;
bool isleft = true;
if (gg != NULL&&gg->rnode == grandpa)
isleft = false;
node->lnode = parent;
node->rnode = grandpa;
parent->parent = node;
grandpa->parent = node;
parent->rnode = node_lnode;
if (node_lnode != NULL)
node_lnode->parent = parent;
grandpa->lnode = node_rnode;
if (node_rnode != NULL)
node_rnode->parent = grandpa;
node->lnode->color = black;
if (gg == NULL)
{
node->parent = NULL;
root = node;
node->color = black;
return;
}
node->parent = gg;
if (isleft)
gg->lnode = node;
else
gg->rnode = node;
}
else if (parent->lnode == node&&grandpa->rnode == parent)
{
RBNode*node_lnode = node->lnode;
RBNode*node_rnode = node->rnode;
RBNode*gg = grandpa->parent;
bool isleft = true;
if (gg != NULL&&gg->rnode == grandpa)
isleft = false;
node->rnode = parent;
node->lnode = grandpa;
parent->parent = node;
grandpa->parent = node;
parent->lnode = node_rnode;
if (node_rnode != NULL)
node_rnode->parent = parent;
grandpa->rnode = node_lnode;
if (node_lnode != NULL)
node_lnode->parent = grandpa;
node->rnode->color = black;
if (gg == NULL)
{
node->parent = NULL;
root = node;
node->color = black;
return;
}
node->parent = gg;
if (isleft)
gg->lnode = node;
else
gg->rnode = node;
}
else if (parent->rnode == node&&grandpa->rnode == parent)
{
RBNode*node_lnode = node->lnode;
RBNode*node_rnode = node->rnode;
RBNode*parent_lnode = parent->lnode;
RBNode*gg = grandpa->parent;
bool isleft = true;
if (gg != NULL&&gg->rnode == grandpa)
isleft = false;
KeyType temp = node->ele;
node->ele = parent->ele;
parent->ele = temp;
node->rnode = parent;
node->lnode = grandpa;
parent->parent = node;
grandpa->parent = node;
parent->rnode = node_rnode;
if (node_rnode != NULL)
node_rnode->parent = parent;
parent->lnode = node_lnode;
grandpa->rnode = parent_lnode;
if (parent_lnode != NULL)
parent_lnode->parent = grandpa;
if (node_lnode != NULL)
node_lnode->parent = parent;
node->rnode->color = black;
if (gg == NULL)
{
node->parent = NULL;
root = node;
node->color = black;
return;
}
node->parent = gg;
if (isleft)
gg->lnode = node;
else
gg->rnode = node;
}
else if (parent->lnode == node&&grandpa->lnode == parent)
{
RBNode*node_rnode = node->rnode;
RBNode*node_lnode = node->lnode;
RBNode*parent_rnode = parent->rnode;
RBNode*gg = grandpa->parent;
bool isleft = true;
if (gg != NULL&&gg->rnode == grandpa)
isleft = false;
KeyType temp = node->ele;
node->ele = parent->ele;
parent->ele = temp;
node->lnode = parent;
node->rnode = grandpa;
parent->parent = node;
grandpa->parent = node;
parent->rnode = node_rnode;
if (node_rnode != NULL)
node_rnode->parent = parent;
parent->lnode = node_lnode;
if (node_lnode != NULL)
node_lnode->parent = parent;
grandpa->lnode = parent_rnode;
if (parent_rnode != NULL)
parent_rnode->parent = grandpa;
node->lnode->color = black;
if (gg == NULL)
{
node->parent = NULL;
root = node;
node->color = black;
return;
}
node->parent = gg;
if (isleft)
gg->lnode = node;
else
gg->rnode = node;
}
else
_ASSERTE(1 < 0);
}
}
bool RBTree::insert(const KeyType val)
{
if (root == NULL)
{
root = new RBNode;
root->color = black;
root->ele = val;
root->lnode = root->rnode = root->parent = NULL;
return true;
}
RBNode*pos = findminmax(val);
if (pos == NULL)//要插入的值比当前树中所有的都大
{
RBNode*nn = root;
while (nn->rnode != NULL)
{
nn = nn->rnode;
}
if (nn->color == black)//包含nn==root的情况
{
RBNode*node = new RBNode;
node->ele = val;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = nn;
nn->rnode = node;
return true;
}
if (nn->color == red)
{
_ASSERTE(nn->lnode == NULL);
//此时nn的父亲颜色一定是黑色
if (nn->parent->lnode == NULL)
{
int temp = nn->parent->ele;
nn->parent->ele = nn->ele;
nn->ele = val;
RBNode*node = new RBNode;
node->ele = temp;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = nn->parent;
nn->parent->lnode = node;
return true;
}
//如果nn->parent->lnode != NULL
_ASSERTE(nn->parent->lnode->color == red);
if (nn->parent == root)
{
RBNode*node = new RBNode;
node->ele = val;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = nn;
nn->rnode = node;
nn->color = black;
root->lnode->color = black;
return true;
}
RBNode*pp = nn->parent;
_ASSERTE(pp != NULL);
RBNode*mm = pp;
_ASSERTE(mm != NULL);
int n = 1;
while (mm->rnode != NULL)
{
mm = mm->rnode;
n++;
}
RBNode*node = new RBNode;
node->ele = val;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = nn;
nn->rnode = node;
insert_adjust(node);
return true;
}
}
if (pos != NULL)
{
if (pos->lnode == NULL)
{
RBNode*node = new RBNode;
node->ele = val;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = pos;
pos->lnode = node;
insert_adjust(node);
return true;
}
RBNode*kk = pos->lnode;
while (kk->rnode != NULL)
{
kk = kk->rnode;
}
RBNode*node = new RBNode;
node->ele = val;
node->color = red;
node->lnode = node->rnode = NULL;
node->parent = kk;
kk->rnode = node;
insert_adjust(node);
return true;
}
}
bool RBTree::isfullblack(RBTree::RBNode*node)
{
std::deque<RBNode*>aa, cc;
int k = 0;
aa.push_back(node);
while (true)
{
while (!aa.empty())
{
RBNode*bb = aa.back();
aa.pop_back();
if (bb->color == red)
return false;
if (bb->lnode != NULL)
cc.push_back(bb->lnode);
if (bb->rnode != NULL)
cc.push_back(bb->rnode);
}
if (cc.empty())
return true;
if (cc.size() != (2 << k))
return false;
aa = cc;
cc.clear();
k++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
RBTree rbt;
RBTree::RBNode*root;
rbt.insert(100);
root = rbt.getRoot();
rbt.insert(700);
root = rbt.getRoot();
rbt.insert(500);
root = rbt.getRoot();
rbt.insert(1000);
root = rbt.getRoot();
rbt.insert(1500);
root = rbt.getRoot();
rbt.insert(600);
root = rbt.getRoot();
rbt.insert(300);
root = rbt.getRoot();
rbt.insert(800);
root = rbt.getRoot();
rbt.insert(3000);
root = rbt.getRoot();
rbt.insert(900);
root = rbt.getRoot();
rbt.insert(1300);
root = rbt.getRoot();
rbt.insert(1800);
root = rbt.getRoot();
system("pause");
return 0;
}</span>