第13章 红黑树

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#define RED 1
#define BLACK 0
using namespace std;
struct node{
	int color;
	int key;
	node* left;
	node* right;
	node* parent;
};

//左旋
void leftRotate(node* &root, node* x)
{
	node* y = x->right;
	if (x->right = y->left) y->left->parent = x;
	if (y->parent = x->parent){
		if (x == x->parent->left) x->parent->left = y;
		else x->parent->right = y;
	}
	else root = y;
	x->parent = y;
	y->left = x;
}
//右旋(x-y,left-right)
void rightRotate(node* &root, node* y)
{
	node* x = y->left;
	if (y->left = x->right) x->right->parent = y;
	if (x->parent = y->parent){
		if (y = y->parent->right) y->parent->right = x;
		else y->parent->left = x;
	}
	else root = x;
	y->parent = x;
	x->right = y;
}
void RBinsertFixup(node* &root, node* z)
{
	while (z->parent && z->parent->color == RED){
		if (z->parent == z->parent->parent->left){	//父节点为左支
			node* y = z->parent->parent->right;
			if (y&&y->color == RED){					//case 1:父节点及其兄弟节点为RED。处理如下:
				z->parent->color = BLACK;						//父节点及其兄弟节点变为BLACK
				y->color = BLACK;
				y->parent->color = RED;							//祖父节点变为RED
				z = y->parent;									//将祖父节点变为当前节点 z
			}
			else{										
				if (z == z->parent->right){				//case 2:父节点为RED,叔叔节点为BLACK,且 z 为父节点的右子节点。处理如下:
					z = z->parent;								//对父节点进行左旋操作,使之成为 case 3
					leftRotate(root, z);
				}										
														//case 3:父节点为RED,叔叔节点为BLACK,且 z 为父节点的左子节点。处理如下:
				z->parent->color = BLACK;						//父节点变为 BLACK
				z->parent->parent->color = RED;					//祖父节点变为 RED
				rightRotate(root, z->parent->parent);			//对祖父节点进行右旋
			}
		}
		else{										//父节点为右支
			node *y = z->parent->parent->left;
			if (y&&y->color == RED){
				z->parent->color = BLACK;
				y->color = BLACK;
				y->parent->color = RED;
				z = y->parent;
			}
			else{
				if (z == z->parent->left){
					z = z->parent;
					rightRotate(root, z);
				}

				z->parent->color = BLACK;
				z->parent->parent->color = RED;
				leftRotate(root, z->parent->parent);
			}
		}
	}
	root->color = BLACK;
}
void RBinsert(node* &root, int val)
{
	node* z = (node*)malloc(sizeof(node));
	node *y = NULL, *x = root;
	while (x){
		y = x;
		if (x->key > val) x = x->left;
		else if (x->key < val) x = x->right;
		else return;
	}
	z->parent = y;
	if (y == NULL) root = z;
	else if (y->key > val) y->left = z;
	else y->right = z;
	z->left = z->right = NULL;
	z->key = val;
	z->color = RED;
	RBinsertFixup(root, z);
}
void RBtransplant(node* &root, node* u, node* v)
{
	if (u->parent == NULL) root = v;
	else if (u == u->parent->left) u->parent->left = v;
	else u->parent->right = v;
	if (v) v->parent = u->parent;
}
void RBdeleteFixup(node* &root, node* x,node* p_x)
{
	node *w;								// x 的父节点的兄弟节点
	while ((!x || x->color == BLACK) && x != root){
		if (x == p_x->left){				// x 的父节点为祖父节点的左支
			w = p_x->right;
			if (w->color == RED){				//case 1: w 是 RED,通过左旋,使之成为 case 2,3,4:
				w->color = BLACK;
				p_x->color = RED;
				leftRotate(root, p_x);
				w = p_x->right;
			}									
			if ((w->left == NULL || w->left->color == BLACK) && (w->right == NULL || w->right->color == BLACK)){
				w->color = RED;					//case 2: w 是 BLACK, 左 BLACK 右 BLACK
				x = p_x;
				p_x = p_x->parent;
			}
			else{								
				if (w->right == NULL || w->right->color == BLACK){
					if (w->left) w->left->color = BLACK;		//case 3: w 是 BLACK, 左 RED 右 BLACK
					w->color = RED;
					rightRotate(root, w);
					w = p_x->right;
				}
				w->color = p_x->color;							//case 4: w 是 BLACK, 右 RED
				p_x->color = BLACK;
				if (w->right) w->right->color = BLACK;
				leftRotate(root, p_x);
				break;
			}
		}
		else{								// x 的父节点为祖父节点的右支
			w = p_x->left;
			if (w->color == RED){
				w->color = BLACK;
				p_x->color = RED;
				rightRotate(root, p_x);
				w = p_x->left;
			}
			if ((w->left == NULL || w->left->color == BLACK) && (w->right == NULL || w->right->color == BLACK)){
				w->color = RED;
				x = p_x;
			}
			else{
				if (w->left == NULL || w->left->color == BLACK){
					if (w->right) w->right->color = BLACK;
					w->color = RED;
					leftRotate(root, w);
					w = p_x->left;
				}
				w->color = p_x->color;
				p_x->color = BLACK;
				if (w->left) w->left->color = BLACK;
				rightRotate(root, p_x);
				break;
			}
		}
	}
	if (x) x->color = BLACK;
}
node* RBdelete(node* &root, int val)
{
	node* z = root;
	while (z){
		if (z->key > val) z = z->left;
		else if (z->key < val) z = z->right;
		else break;
	}
	if (z == NULL) return NULL;
	node* y = z, *x, *p_x;
	int colory = y->color;
	if (z->left == NULL){
		x = z->right;
		p_x = z->parent;
		RBtransplant(root, z, z->right);
	}
	else if (z->right == NULL){
		x = z->left;
		p_x = z->parent;
		RBtransplant(root, z, z->left);
	}
	else{
		y = z->right;
		while (y->left) y = y->left;
		colory = y->color;
		x = y->right;
		p_x = y->parent;
		z->key = y->key;
		RBtransplant(root, y, y->right);
	}
	free(y);
	if (colory == BLACK){
		RBdeleteFixup(root, x, p_x);
	}
	return x;
}
void printRB(node* root)
{
	node *p;
	queue<node*> q;
	q.push(root);
	while (!q.empty()){
		p = q.front(); q.pop();
		if (p){
			printf("%d", p->key);
			if (p->color == RED) printf("r ");
			else printf("b ");
			q.push(p->left);
			q.push(p->right);
		}
		else printf("- ");
	}
	printf("
");
}
int main()
{
	int a[] = { 11, 3, 14, 1, 7, 15, 5, 8, 4 };
	for (int j = 1; j < 10; ++j){
		node* root = NULL;
		for (int i = 0; i < j; ++i)
			RBinsert(root, a[i]);
		printRB(root);
	}
	printf("

");
	for (int k = 0; k < 9; ++k){
		node* root = NULL;
		for (int i = 0; i < 9; ++i)
			RBinsert(root, a[i]);
		node* x=RBdelete(root, a[k]);
		printRB(root);
	}

}

  

原文地址:https://www.cnblogs.com/jokoz/p/4739146.html