#include <iostream>
#include<stack>
using namespace std;
/*
1:红黑树结点有三个指针域,分别指向父节点,左孩子,右孩子
有一个数据域,有一个标志域(红,黑),提供一个列表初始化构造函数
2:构造一棵红黑树:
2.1:先构造一棵二叉排序树;
2.2:分类调整
3:parent为红时调整
3.1 uncle存在且为红:
爷变红,父叔变黑,递归向上
3.2 uncle不存在或uncle存在且为黑
3.2.1 子在父爷右侧(单向左旋,爷变红,父变黑)
3.2.2 子在父爷左侧(单向右旋,爷变红,父变黑)
3.2.3 子在爷右父左(先右旋后左旋,爷变红,子变黑)
3.2.4 子在爷右父左(先左旋后右旋,爷变红,子变黑)
4.插入函数最后要将root设置为黑色
*/
enum Color {RED,BLACK};
typedef int datatype;
typedef struct Node {
datatype _data;
Node* _left;
Node* _right;
Node* _parent;
Color _col;
//列表初始化构造函数
Node(datatype data):_data(data),_left(nullptr),_right(nullptr),_parent(nullptr),_col(RED){}
}Node;
struct RBTree {
public:
Node* _root=nullptr;
public:
//左单旋
void lrotate(Node* T)
{
Node* x = T->_right;
Node* y = x->_left;
T->_right = y;
if (y)
y->_parent = T;
//先保存一下T->_T,因为下面会改它
Node* pT = T->_parent;
x->_left = T;
T->_parent = x;
//若pT为空则证明旋转的是一整棵树,因为根结点的_parent为空
if (pT == nullptr)
{
//x是新的根
_root = x;
_root->_parent = nullptr;
}
//若pT不为空,则证明旋转的是子树,T上面还有结点
else
{
//让pT指向子树旋转之后新的根
if (pT->_left == T)
{
pT->_left = x;
}
else
{
pT->_right = x;
}
//同时也让新的根指向pT
x->_parent = pT;
}
}
//右单旋
void rrotate(Node* T)
{
Node* x = T->_left;
Node* y = x->_right;
//旋转并更新_T指针
T->_left = y;
if (y)
y->_parent = T;
//先保存一下T->_parent,因为下面会改它
Node* pT = T->_parent;
//旋转并更新_T指针
x->_right = T;
T->_parent = x;
//若T等于_root则证明旋转的是一整棵树(这也是一种判断方法)
if (T == _root)
{
_root = x;
x->_parent = nullptr;
}
else
{
//让pT指向子树旋转之后新的根
if (T == pT->_left)
{
pT->_left = x;
}
else
{
pT->_right = x;
}
//同时也让新的根指向pT
x->_parent = pT;
}
}
//插入
bool insert(datatype data) {
if (_root == nullptr) {
_root = new Node(data);
_root->_col = BLACK;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur) {
if (data < cur->_data) {
parent = cur;
cur = cur->_left;
}
else if (data > cur->_data) {
parent = cur;
cur = cur->_right;
}
else {
return parent?false:true; //parent为空时,插入的是根结点,返回true,插入成功
}
}
//到这里时cur为空
cur = new Node(data);
cur->_parent = parent;
if (data < parent->_data) {
parent->_left = cur;
}
if (data > parent->_data) {
parent->_right = cur;
}
//插入完成,检查
while (parent && parent->_col == RED)
{
Node* g = parent->_parent;
if (parent == g->_left) //左边插入
{
Node* uncle = g->_right;
if (uncle && uncle->_col == RED) { //叔存在且为红
g->_col = RED;
parent->_col = BLACK;
uncle->_col = BLACK;
cur = g;
parent = cur->_parent; //向上递归
}
else { //叔不存在或为黑
if (cur == parent->_left) { //属于LL,单右旋
rrotate(g);
g->_col = RED;
parent->_col = BLACK;
}
else { //属于LR,先左旋后右旋
lrotate(parent);
rrotate(g);
cur->_col = BLACK;
g->_col = RED;
}
break;
}
}
else //右边插入parent==g->_right
{
Node* uncle = g->_left;
if (uncle && uncle->_col == RED) //叔存在且为红
{
g->_col = RED;
parent->_col = BLACK;
uncle->_col = BLACK;
cur = g;
parent = cur->_parent;
}
else {//叔不存在或存在且为黑
if (cur == parent->_right) { //属于RR,单向左旋
lrotate(g);
g->_col = RED;
parent->_col = BLACK;
}
else { //属于RL,先右旋后左旋
rrotate(parent);
lrotate(g);
cur->_col = BLACK;
g->_col = RED;
}
break;
}
}
}//while,在while里面检查,旋转,变色
_root->_col = BLACK;
return true;
}//insert
};//RBTree
//先序遍历
void prePrint(Node* T) {
if (T) {
cout << T->_data << " ";
prePrint(T->_left);
prePrint(T->_right);
}
}
//中序遍历二叉排序树,借助一个栈
void inPrint(Node* T) {
stack<Node*> s;
while (T || !s.empty()) {
if (!T) {//T为空
Node* p = s.top();
cout << p->_data << " ";
T = p->_right;
s.pop();
}
else {
s.push(T);
T = T->_left;
}
}
}
void main() {
RBTree tree;
int x[] = { 5,8,6,4,7,2,1,64,21,15,13,14,10,12 };
int len = sizeof(x) / sizeof(x[0]);
for (int i = 0;i < len;i++) {
tree.insert(x[i]);
}
prePrint(tree._root);
cout << endl;
inPrint(tree._root);
system("pause");
}

911

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



