#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//红黑树学习,主要难点,左旋,右旋,插入,删除
//红黑树主要是为了保证二叉搜索树的平衡,避免出现一条简单路径的深度高,一条简单路径深度低的情况
//红黑树的效率高,保证在最坏的情况下的时间复杂度的为O(lgn)
//红黑树的五条性质:
//1.每个节点或是红色的,或是黑色的
//2.根节点是黑色的
//3.每个叶节点(NIL)是黑色的
//4.如果一个节点是红色的,则它的两个子结点都是黑色的
//5.对每个结点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色结点
//*************************数据结构定义阶段*************************
typedef enum{RED,BLACK} Color;
typedef struct BST{
int key; //关键字
Color color;//节点颜色
struct BST *p,*left,*right; //双亲,左孩,右孩
BST(){color = BLACK; p = left = right = NULL;} //无参构造
}BSTNode;
typedef struct BST_Root{ //树根
BSTNode *root;
BSTNode *nil; //红黑树是以一个标记结尾的
BST_Root(){ //
nil = new BSTNode();
nil->color = BLACK;
nil->p = nil->left = nil->right = NULL;
root = nil;
}
}BSTRoot;
BSTRoot BT; //这里我直接把树根先建好,后面方便使用nil
//*************************数据结构定义阶段*************************
//*************************查找*************************
//和一般的二叉搜索树一样的操作,只是结尾标志不再是NULL,而是统一的nil
BSTNode* tree_search(BSTNode *&T,int k){ //递归查找
if(T != BT.nil && T->key != k){
if(k < T->key)
return tree_search(T->left,k);
else
return tree_search(T->right,k);
}
return T;
}
BSTNode* interative_tree_search(BSTNode *&T,int k){ //非递归查找
BSTNode *t = T;
while(t != BT.nil && t->key != k){
if(k < t->key)
t = t->left;
else
t = t->right;
}
return t;
}
//*************************查找*************************
//************************最大关键字查询,最小关键字查询,前驱和后继查询************************
BSTNode* tree_minmum(BSTNode *&T){ //最小关键字查询
BSTNode *t = T;
while(t!=BT.nil && t->left != BT.nil){
t = t->left;
}
return t;
}
BSTNode* tree_maxmum(BSTNode *&T){ //最大关键字查询
BSTNode *t = T;
while(t!=BT.nil && t->right != BT.nil){
t = t->right;
}
return t;
}
BSTNode* tree_successor(BSTNode *&T){ //后继查询,后继就是大于T.x的最小关键字节点
BSTNode *t = T,*y = BT.nil;
if(T == BT.nil) return T;
if(T->right != BT.nil) //如果右子树不为空直接求右子树的最小节点
return tree_minmum(T->right);
y = t->p;
while(y != BT.nil && y->right == t){
t = y;
y = y->p;
}
return y;
}
BSTNode* tree_predecessor(BSTNode *&T){ //前驱查询,前驱就是小于T.x的最大关键字节点
BSTNode *t = T,*y = BT.nil;
if(T == BT.nil) return T;
if(T->left != BT.nil) //如果左子树不为空直接求左子树的最大节点
return tree_maxmum(T->left);
y = t->p;
while(y != BT.nil && y->left == t){ //这里就是没有左子树的情况,往上找,上面还有没有小于t.x的节点
t = y;
y = y->p;
}
return y;
}
//************************最大关键字查询,最小关键字查询,前驱和后继查询************************
//************************左旋和右旋************************
void left_rotate(BSTNode *&T,BSTNode *& x){
BSTNode *y = x->right; //x的右孩取出来
x->right = y->left; //把y的左孩给x当右孩
if(y->left != BT.nil){ //y的左孩不是nil就让它认x为爸
y->left->p = x;
}
y->p = x->p;
if(x->p == BT.nil) //如果x原来是根节点,那么更新根节点
BT.root = y;
else if(x == x->p->left) //看x原来是它父节点的左孩还是右孩,因为从现在开始x不是它原来父节点的儿了,y才是
x->p->left = y;
else
x->p->right = y;
y->left = x;
x->p = y;
}
void right_rotate(BSTNode *&T,BSTNode *&y){ //右旋,同上面是对称的
BSTNode *x = y->left;
y->left = x->right;
if(x->right != BT.nil)
x->right->p = y;
x->p = y->p;
if(y->p == BT.nil)
BT.root = x;
else if(y == y->p->left)
y->p->left = x;
else
y->p->right = x;
x->right = y;
y->p = x;
}
//************************左旋和右旋************************
//************************插入************************
void RB_Insert_Fixup(BSTNode *&T,BSTNode *&z){
//要判断父节点是红色才用调整,黑色直接插入
while(z->p->color == RED){
//先确定父节点是祖父节点的左孩还是右孩
if(z->p == z->p->p->left){ //这里是左孩
BSTNode* y = z->p->p->right; //找到祖父节点的右孩,就是叔节点
if(y->color == RED){ //如果叔节点是红色的
//第一种情况
z->p->color = BLACK; //那么把祖父的两个孩节点都变成黑色,然后祖父节点变成红色,z在移到祖父节点的位置
y->color = BLACK;
z->p->p->color = RED;
z = z->p->p;
} else if(z == z->p->right){ //说明叔节点是黑色的,并且z是它父节点的右孩,那么对z的父节点左旋
//第二种情况
z = z->p;
left_rotate(T,z);
}else{
//第三种情况 说明叔节点是黑色的,并且z是它父节点的左孩,那么对z的父节点右旋
z->p->color = BLACK;
z->p->p->color = RED;
right_rotate(T,z->p->p);
}
}else{ //这里是祖父节点的右孩,那么操作与上面对称
BSTNode* y = z->p->p->left;
if(y->color == RED){
y->color = BLACK;
z->p->color = BLACK;
z->p->p->color = RED;
z = z->p->p;
}else if(z == z->p->left){
z = z->p;
right_rotate(T,z);
}else{
z->p->color = BLACK;
z->p->p->color = RED;
left_rotate(T,z->p->p);
}
}
}
BT.root->color = BLACK;
}
void tree_insert(BSTNode *&T, int k){ //插入操作基本一样,就最后多了两步
BSTNode *t = T,*y = BT.nil;
BSTNode *z = new BSTNode();
z->key = k;
z->p = z->left = z->right = BT.nil;
z->color = RED; //这里要把颜色设置为红色
while(t!=BT.nil){
y = t;
if(k < t->key)
t = t->left;
else
t = t->right;
}
z->p = y;
if(y == BT.nil)
BT.root = z;
else if(k < y->key)
y->left = z;
else
y->right = z;
RB_Insert_Fixup(T,z); //调整颜色,保持红黑性质
}
//************************插入************************
//************************删除************************
void tree_transplant(BSTNode *&T,BSTNode *&u,BSTNode *&v){
if(u->p == BT.nil)
BT.root = v;
else if(u == u->p->left)
u->p->left = v;
else
u->p->right = v;
v->p = u->p;
}
void RB_Delete_Fixup(BSTNode *&T,BSTNode *&x){
while(x != T && x->color == BLACK){
if(x == x->p->left){
BSTNode *w = x->p->right;
if(w->color == RED){
w->color = BLACK;
x->p->color = RED;
left_rotate(T,x->p);
w = x->p->right;
}
if(w->left->color == BLACK && w->right->color == BLACK){
w->color = RED;
x = x->p;
}else if(w->right->color == BLACK){
w->left->color = BLACK;
w->color = RED;
right_rotate(T,w);
w = x->p->right;
}
w->color = x->p->color;
x->p->color = BLACK;
w->right->color = BLACK;
left_rotate(T,x->p);
x = T;
}else{
BSTNode *w = x->p->left;
if(w->color == RED){
w->color = BLACK;
x->p->color = RED;
right_rotate(T,x->p);
w = x->p->left;
}
if(w->left->color == BLACK && w->right->color == BLACK){
w->color = RED;
x = x->p;
}else if(w->right->color == BLACK){
w->color = RED;
w->right->color = BLACK;
w = x->p->left;
}
w->color = w->p->color;
x->p->color = BLACK;
w->right->color = BLACK;
right_rotate(T,x->p);
x = T;
}
}
x->color = BLACK;
}
void tree_delete(BSTNode *&T,BSTNode *&z){ //删除
BSTNode *y = z,*x;
Color y_color = y->color;
if(z->left == BT.nil){ //左子树为空
x = z->right;
tree_transplant(T,z,z->right);
}else if(z->right == BT.nil){ //右子树为空
x = z->left;
tree_transplant(T,z,z->left);
}else{ //左右子树不为空
y = tree_minmum(z->right);
y_color = y->color;
x = y->right;
if(y->p == z)
x->p = y;
else {
tree_transplant(T,y,y->right);
y->right = z->right;
y->right->p = y;
}
tree_transplant(T,z,y);
y->left = z->left;
y->left->p = y;
y->color = z->color;
}
if(y_color == BLACK)
RB_Delete_Fixup(T,x);
}
//************************删除************************
void inorder_input(BSTNode *&T){ //中序遍历输出
if(T!=BT.nil){
inorder_input(T->left);
printf("%d ",T->key);
inorder_input(T->right);
}
}
int main(){
int a[9] = {11,2,14,1,7,15,5,8,4};
for(int i = 0;i<9;i++)
tree_insert(BT.root,a[i]);
printf("inorder input primitive sequence: ");
inorder_input(BT.root);
putchar('\n');
printf("after digit 3 be deleted: ");
BSTNode *z = tree_search(BT.root,7);
tree_delete(BT.root, z);
inorder_input(BT.root);
putchar('\n');
system("pause");
return 0;
}