#include<iostream>
#include<stack>
#include<vector>
using namespace std;
const bool black = 0;
const bool red = 1;
struct RBNode
{
int key;
bool color;
RBNode *llink, *rlink, *parent;
};
class RBTree
{
public:
RBTree();
~RBTree();
int insertNode(int key); //插入元素接口
int deleteNode(int key); //删除元素接口
void nPreOrder(); //先序遍历非递归
void nInOrder(); //中序遍历非递归
void nPostOrder(); //后序遍历非递归
bool isRBTree(); //验证是否是红黑树
private:
void destroy(RBNode **proot); //销毁树,析构函数用到
RBNode *createNode(int key); //生成红黑树结点
void insertFixup(RBNode *pnode); //插入元素后调整
RBNode *searchNode(int key); //找指定元素的结点,删除元素函数用到
void transplant(RBNode *v0, RBNode *v1); //删除指定结点,删除元素函数用到
RBNode *minNode(RBNode *x); //找到树中最小的元素,删除元素函数用到
void deleteFixup(RBNode *delNode); //删除元素后调整
RBNode *rotate_right(RBNode *a); //右旋
RBNode *rotate_left(RBNode *a); //左旋
RBTree(const RBTree &obj);
RBTree &operator=(const RBTree &obj);
RBNode *root;
RBNode *m_null;
};
//构造函数
RBTree::RBTree()
{
m_null = new RBNode;
m_null->color = black;
m_null->llink = m_null->rlink = m_null;
root = m_null;
}
//析构函数
RBTree::~RBTree()
{
if (root != m_null)
{
destroy(&root);
root = NULL;
}
delete m_null;
m_null = NULL;
}
//插入元素
int RBTree::insertNode(int key)
{
RBNode *p = root;
RBNode *parent = m_null;
while (p != m_null)
{
parent = p;
if (key == p->key)
{
return -1;
}
else if (key < p->key)
{
p = p->llink;
}
else
{
p = p->rlink;
}
}
RBNode *newNode = createNode(key);
if (parent == m_null)
{
root = newNode;
root->color = black;
}
else
{
if (key < parent->key)
{
parent->llink = newNode;
}
else
{
parent->rlink = newNode;
}
newNode->parent = parent;
insertFixup(newNode); //插入元素后调整
}
return 0;
}
//插入元素后调整
void RBTree::insertFixup(RBNode *pnode)
{
RBNode *parent = pnode->parent;
RBNode *grandParent = m_null;
while (parent != m_null&&parent->color == red) //迭代
{
grandParent = parent->parent;
if (parent == grandParent->llink)
{
RBNode *uncle = grandParent->rlink;
if (uncle->color == red) //情况1
{
parent->color = black;
uncle->color = black;
grandParent->color = red;
pnode = grandParent;
parent = pnode->parent;
}
else
{
if (pnode == parent->rlink) //情况2,可转换为情况3
{
pnode = rotate_left(parent);
parent = pnode->parent;
grandParent = parent->parent;
}
parent->color = black; //情况3
grandParent->color = red;
rotate_right(grandParent);
}
}
else //与上面对称
{
RBNode *uncle = grandParent->llink;
if (uncle->color == red)
{
parent->color = black;
uncle->color = black;
grandParent->color = red;
pnode = grandParent;
parent = pnode->parent;
}
else
{
if (pnode == parent->llink)
{
pnode = rotate_right(parent);
parent = pnode->parent;
grandParent = parent->parent;
}
parent->color = black;
grandParent->color = red;
rotate_left(grandParent);
}
}
}
root->color = black;
}
//寻找指定键值元素
RBNode *RBTree::searchNode(int key)
{
RBNode *p = root;
while (p != m_null)
{
if (key == p->key)
{
return p;
}
else if (key < p->key)
{
p = p->llink;
}
else
{
p = p->rlink;
}
}
return m_null;
}
//删除元素后调整各结点关系
void RBTree::transplant(RBNode *v0, RBNode *v1)
{
if (v0 == root)
{
root = v1;
root->parent=m_null;
}
else if (v0 == v0->parent->llink)
{
v0->parent->llink = v1;
}
else
{
v0->parent->rlink = v1;
}
v1->parent = v0->parent;
}
//找到树中最小健值结点
RBNode *RBTree::minNode(RBNode *x)
{
while (x->llink != m_null)
{
x = x->llink;
}
return x;
}
//删除指定健值结点
int RBTree::deleteNode(int key)
{
RBNode *delNode = searchNode(key); //寻找删除的结点
if (delNode == m_null)
{
return -1;
}
RBNode *realDel = delNode; //实际删除的结点赋初值
RBNode *replace = m_null; //代替的结点
if (delNode->rlink == m_null) //如果删除的结点最多只有1棵子树
{
replace = delNode->llink;
}
else if (delNode->llink == m_null)
{
replace = delNode->rlink;
}
else //如果有两个子树
{
realDel = minNode(delNode->rlink); //找到右子树最小结点,即为实际要删除的结点
replace = realDel->rlink;
delNode->key = realDel->key; //实际删除的结点值赋给删除的结点
}
transplant(realDel, replace);
if (realDel->color == black)
{
deleteFixup(replace); //如果实际删除的结点是黑色,则调整
}
delete realDel;
return 0;
}
//删除结点后调整
void RBTree::deleteFixup(RBNode *delNode)
{
RBNode *p = delNode;
while (p != root&&p->color == black)
{
RBNode *parent = p->parent;
if (p == parent->llink)
{
RBNode *slibing = parent->rlink;
if (slibing->color == red) //情况1,兄弟结点为红色 可转换为情况2,3,4
{ //兄弟结点涂成黑色,父结点凃成红色,以父结点为支点左旋
parent->color = red;
slibing->color = black;
rotate_left(parent);
slibing = parent->rlink; //调整兄弟结点
}
//此时兄弟结点肯定为黑色
if (slibing->llink->color == black&&slibing->rlink->color == black) //情况2,两个侄子结点都为黑色
{
slibing->color = red; //兄弟结点凃红
p = parent; //父结点为当前节点
}
else
{
if (slibing->rlink->color == black) //情况3,左侄子结点为红色
{
slibing->color = red; //兄弟凃红
slibing->llink->color = black; //左侄子凃红
rotate_right(slibing); //以兄弟为支点右旋
slibing = slibing->parent; //调整兄弟结点转换为情况4
}
slibing->color = parent->color; //情况4 ,右侄子为红
parent->color = black; //父结点与兄弟结点交换颜色
slibing->rlink->color = black; //右侄子凃黑后结束
rotate_left(parent); //以父结点为支点左旋
p = root;
}
}
else //与上面对称
{
RBNode *slibing = parent->llink;
if (slibing->color == red)
{
slibing->color = black;
parent->color = red;
rotate_right(parent);
slibing = parent->llink;
}
if (slibing->llink->color == black&&slibing->rlink->color == black)
{
slibing->color = red;
p = parent;
}
else
{
if (slibing->llink->color == black)
{
slibing->color = red;
slibing->rlink->color = black;
rotate_left(slibing);
slibing = slibing->parent;
}
slibing->color = parent->color;
parent->color = black;
slibing->llink->color = black;
rotate_right(parent);
p = root;
}
}
}
p->color = black;
}
//右旋
RBNode *RBTree::rotate_right(RBNode *a)
{
RBNode *b = a->llink;
if (b == m_null)
{
return a;
}
a->llink = b->rlink;
b->rlink->parent = a;
if (root == a)
{
root = b;
b->parent = m_null;
}
else
{
if (a->parent->llink == a)
{
a->parent->llink = b;
}
else
{
a->parent->rlink = b;
}
b->parent = a->parent;
}
b->rlink = a;
a->parent = b;
return a;
}
//左旋
RBNode *RBTree::rotate_left(RBNode *a)
{
RBNode *b = a->rlink;
if (b == m_null)
{
return a;
}
a->rlink = b->llink;
b->llink->parent = a;
if (root == a)
{
root = b;
b->parent = m_null;
}
else
{
if (a->parent->llink == a)
{
a->parent->llink = b;
}
else
{
a->parent->rlink = b;
}
b->parent = a->parent;
}
b->llink = a;
a->parent = b;
return a;
}
//销毁树,析构函数调用
void RBTree::destroy(RBNode **proot)
{
if (*proot == m_null)
{
return;
}
destroy(&(*proot)->llink);
destroy(&(*proot)->rlink);
delete *proot;
*proot = m_null;
}
RBNode *RBTree::createNode(int key)
{
RBNode *p = new RBNode;
if (p)
{
p->color = red;
p->key = key;
p->llink = p->rlink = p->parent = m_null;
}
return p;
}
//先序遍历非递归
void RBTree::nPreOrder()
{
if (root == m_null)
{
return;
}
stack<RBNode*> st;
RBNode *p = root;
st.push(p);
while (!st.empty())
{
p = st.top();
st.pop();
if (p != m_null)
{
cout << p->key << ' ';
st.push(p->rlink);
st.push(p->llink);
}
}
cout << endl;
}
//中序遍历非递归
void RBTree::nInOrder()
{
if (root == m_null)
{
return;
}
stack<RBNode*> st;
RBNode *p = root;
while (p != m_null || !st.empty())
{
while (p != m_null)
{
st.push(p);
p = p->llink;
}
p = st.top();
st.pop();
cout << p->key << ' ';
p = p->rlink;
}
cout << endl;
}
//后序遍历非递归
void RBTree::nPostOrder()
{
if (root == m_null)
{
return;
}
stack<RBNode*> st;
RBNode *p = root;
RBNode *pp = m_null;
while (p != m_null || !st.empty())
{
while (p != m_null)
{
st.push(p);
pp = p->rlink;
p = p->llink;
if (p == m_null)
{
p = pp;
}
}
p = st.top();
st.pop();
cout << p->key << ' ';
if (!st.empty() && st.top()->llink == p)
{
p = st.top()->rlink;
}
else
{
p = m_null;
}
}
cout << endl;
}
//判断是否是红黑树
bool RBTree::isRBTree()
{
if (root == m_null)
{
return true;
}
vector<RBNode*> st;
RBNode *p=root;
RBNode *pp=m_null;
int num=0;
int black_num=0;
//1、根节点是黑色
if(p->color==red)
return false;
while(p!=m_null||!st.empty())
{
while(p!=m_null)
{
st.push_back(p);
pp=p->rlink;
p=p->llink;
if(p==m_null)
p=pp;
}
p=st.back();
st.pop_back();
//2、每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
if(p->color==red&&(p->llink->color!=black||p->rlink->color!=black))
return false;
//3、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
if(p->llink==m_null&&p->rlink==m_null)
{
black_num=0;
for(vector<RBNode*>::iterator iter=st.begin();iter!=st.end();++iter)
{
if((*iter)->color==black)
black_num++;
}
if(p->color==black)
black_num++;
if(num==0)
num=black_num;
else if(num!=black_num)
return false;
}
if(!st.empty()&&st.back()->llink==p)
p=st.back()->rlink;
else
p=m_null;
}
return true;
}
#include<stdlib.h>
#define N 1000
#define random(i) (rand()%i)
int main()
{
RBTree tree;
int num=0;
while(num<N) //插入N个不同的随机节点
{
if(tree.insertNode(random(N))==0)
{
num++;
if(tree.isRBTree()==false) //插入节点后判断是否是红黑树
cout<<"insert error"<<endl;
}
}
tree.nPreOrder();
cout<<"======================"<<endl;
tree.nInOrder();
cout<<"======================"<<endl;
tree.nPostOrder();
cout<<"======================"<<endl;
num=0;
while(num<N) //删除N个不同的随机节点
{
if(tree.deleteNode(random(N))==0)
{
num++;
if(tree.isRBTree()==false) //删除节点后判断是否是红黑树
cout<<"delete error"<<endl;
}
}
return 0;
}
C++实现红黑树与验证
最新推荐文章于 2022-12-20 16:11:42 发布