理论知识参见 《数据结构基础 》 张力译版以下代码与大家分享,如有错误之处希望批评指正。(我已测试通过)
//RedBlackTree.h
#ifndef _REDBLACKTREE_
#define _REDBLACKTREE_
class TreeNode
{
friend class RedBlackTree;
public:
TreeNode(int e)
{
key=e;
rb=0;
leftchild=rightchild=0;
}
private:
int key;
bool rb;//颜色标记0 红 1 black
TreeNode *leftchild, *rightchild;
};
class RedBlackTree
{
public:
RedBlackTree(TreeNode* init=0)
{
root=0;
}
void Insert(const int e);
private:
TreeNode * root;
};
#endif
//RedBlackTree.cpp
#include "RedBlackTree.h"
#include <iostream>
#include <stack>
using namespace std;
void RedBlackTree::Insert(const int e)
{
if (!root)
{
root=new TreeNode(e);
root->rb=1;//根节点始终是黑色
return ;
}
stack<TreeNode*>s;//记录遍历路径
TreeNode *u=root;
TreeNode *pu=0;//u的父节点
TreeNode *gu=0;//u的祖父节点
TreeNode *uu=0;//叔父节点
while(u)//查找插入位置
{
s.push(u);
/*关键字查找*/
if (e==u->key)//已有该关键字
{
return;
}
else if (e<u->key)
{
u=u->leftchild;
}
else
{
u=u->rightchild;
}
}
bool inflag=0; //新节点尚未插入
u=new TreeNode(e);
pu=s.top();//得到父节点
s.pop();
while (1)//一直进行
{
if (s.empty())//s空 仅有父节点
{
//无祖父节点
if (!inflag)// 尚未插入
{
if (e<pu->key)
{
pu->leftchild=u;
}
else if (e>pu->key)
{
pu->rightchild=u;
}
inflag=1;
}
return ;
}
else
{
gu=s.top();
s.pop();
//尚未插入则插入
if (!inflag)// 尚未插入
{
if (e<pu->key)
{
pu->leftchild=u;
}
else if (e>pu->key)
{
pu->rightchild=u;
}
inflag=1;
}
//判断当前的u是否违反性质2 不违反则返回,违反则分类操作
if (pu->rb!=u->rb)//不违反性质2
{
return;
}
else
{
//分类 r b
if (pu==gu->leftchild)
{
uu=gu->rightchild;
}
else
{
uu=gu->leftchild;
}
if (uu&&uu->rb==0)//red 颜色变换 LL 与RL 变换相同
{
if (gu->leftchild==pu)//1L
{
// if (pu->leftchild==u)//2L (LL)
// {
//LLr 颜色变换
gu->rb=0;
uu->rb=1;
pu->rb=1;
// }
// else//2R (LR)
// {
// gu->rb=0;
// uu->rb=1;
// pu->rb=1;
// }
}
else//1R
{
// if (pu->leftchild==u)//2L (RL)
// {
//RLr 颜色变换
gu->rb=0;
uu->rb=1;
pu->rb=1;
// }
// else//2R (RR)
// {
// gu->rb=0;
// uu->rb=1;
// pu->rb=1;
// }
}
u=gu;//准备下次判断、操作
if (!s.empty())
{
pu=s.top();
s.pop();
}
else
{
u->rb=1;//root
}
}
else// b 旋转
{
if (gu->leftchild==pu)//1L
{
if (pu->leftchild==u)//2L (LL)
{
//LLb 旋转
gu->leftchild=pu->rightchild;
pu->rightchild=gu;
pu->rb=1;
gu->rb=0;
}
else//2R (LRb)
{
gu->leftchild=u->rightchild;
pu->rightchild=u->leftchild;
u->leftchild=pu;
u->rightchild=gu;
u->rb=1;
gu->rb=0;
pu->rb=0;
}
}
else//1R
{
if (pu->leftchild==u)//2L (RL)
{
//RLb 旋转
pu->leftchild=u->rightchild;
gu->rightchild=u->leftchild;
u->rightchild=pu;
u->leftchild=gu;
u->rb=1;
gu->rb=0;
pu->rb=0;
}
else//2R (RR)
{
gu->rightchild=pu->leftchild;
pu->leftchild=gu;
pu->rb=1;
gu->rb=0;
}
}
if (!s.empty())
{
pu=s.top();
s.pop();
}
else
{
root=u;
u->rb=1;//root
return;
}
if (e<pu->key)
{
pu->leftchild=u;
}
else
{
pu->rightchild=u;
}
return;
}
}
}
}
}//main.cpp
#include <iostream>
#include "RedBlackTree.h"
using namespace std;
void main()
{
RedBlackTree rbt;
rbt.Insert(50);
rbt.Insert(10);
rbt.Insert(80);
rbt.Insert(90);
rbt.Insert(70);
rbt.Insert(60);
rbt.Insert(65);
rbt.Insert(62);
}

本文详细介绍了一种平衡二叉搜索树——红黑树的插入操作实现过程。通过对红黑树性质的遵循与调整,确保了树的平衡状态。文章通过具体代码示例展示了插入节点后的旋转与颜色调整步骤。
177万+

被折叠的 条评论
为什么被折叠?



