之前在上到算导的红黑树插入时,突然冒出个想法,下课的时候找徐教授交流,由于当时也没想透彻加上表述不清,就没深入下去。恰巧实验课要做红黑树插入的实现,于是整理了一番,记录于此以备以后查看。
由于C++水平太菜,代码基本用C实现,用到了一些C++的新特性。
一、红黑树插入实现
首先是结点的数据结构,一共5个,分别是数据、颜色、指向左右孩子和父结点的指针,具体代码如下
typedef struct rb_node {
elemtype data;
bool color;//红色为true,黑色为false
struct rb_node* left;
struct rb_node* right;
struct rb_node* parent;
} Node, *rbTree;
接着是书上伪代码的实现,一共四个函数:
1、LEFT-ROTATE(T,x)
void LEFT_ROTATE(rbTree &T, Node* x) {
rotate_times++;//全局变量,统计旋转的总次数
Node* y = x->right;
x->right = y->left;
if (y->left != NULL) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL) {
T = y;
}
else if (x == x->parent->left) {
x->parent->left = y;
}
else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
2、RIGHT_ROTATE(T,y)
void RIGHT_ROTATE(rbTree &T, Node* y) {
rotate_times++;//全局变量,统计旋转的总次数
Node* x = y->left;
y->left = x->right;
if (x->right != NULL) {
x->right->parent = y;
}
x->parent = y->parent;
if (y->parent == NULL) {
T = x;
}
else if (y == y->parent->left) {
y->parent->left = x;
}
else {
y->parent->right = x;
}
x->right = y;
y->parent = x;
}
3、RB_INSERT(T,z)
void RB_INSERT(rbTree &T, Node* z) {
Node* y = NULL;
Node* x = T;
//寻找待插入位置
while (x != NULL) {
y = x;
if (z->data < x->data) {
x = x->left;
}
else {
x = x->right;
}
}
z->parent = y;
//将z插入合适位置
if (y == NULL) {
T = z;
}
else if (z->data < y->data) {
y->left = z;
}
else {
y->right = z;
}
z->left = NULL;
z->right = NULL;
z->color = RED;
RB_INSERT_FIXUP(T, z);
}
4、RB_INSERT_FIXUP(T,z)
void RB_INSERT_FIXUP(rbTree &T, Node* z) {
while (z->parent != NULL && z->parent->color == RED) {
//case123父亲是祖父的左孩子
//z父亲为红,则必定存在为黑的祖父
if (z->parent == z->