对于《算法导论》红黑树插入算法的理解

#include <iostream>
using namespace std;

struct TNode {

	//节点颜色枚举类
	enum RBColor
	{
		BLACK = 0,
		RED = 1

	};
	int key;
	RBColor color; 
	TNode* p;
	TNode* left;
	TNode* right;

	
};

class RBTree{

public:
	//树根
	TNode* root;
	//nil几点
	TNode* nil;
	//黑高
	int blackHeight;

	RBTree() {
		nil = new TNode;
		nil->color = TNode::BLACK;
		nil->key = -1; //没有任何意义,防止nil的值不确定
		nil->p = nil->left = nil->right = nil;
		root = nil;

		blackHeight = 0;;

	}

	void RBInsertKey(int key);
	void RBInsertFixup(TNode* z);
	
	void RBLeftRoatate(TNode* x);
	void RBRightRoatate(TNode* x);
	
	void printRBTree(TNode* x);
	void check(TNode* x);

};

void RBTree::RBLeftRoatate(TNode* x) {

	TNode* y = x->right;
	x->right = y->left;

    //3条线,x-y.left,y-x.parent,x-y
	if (y->left != nil) {
		y->left->p = x;
	}
	y->p = x->p;
	
	
	if (x == root) {
		root = y;
	}
	else if(x->p->left == x){
		x->p->left = y;
	}
	else {
		x->p->right = y;
	}
	
	x->p = y;
	y->left = x;

}
void RBTree::RBRightRoatate(TNode* x) {

	TNode* y=x->left;
	x->left = y->right;

	if (y->right != nil) {
		y->right->p = x;
	}
	
	y->p = x->p;

	if (x == root) {
		root = y;
	}
	else if (x->p->left == x) {
		x->p->left = y;
	}
	else {
		x->p->right = y;
	}
    
	x->p = y;
	y->right = x;

}


void RBTree::RBInsertKey(int key) {

	TNode* y = nil;
	TNode* x = root;
	while (x != nil) {
		y = x;
		if (x->key > key) {
			x = x->left;
		}
		else {
			x = x->right;
		}
	}
	
	TNode* temp = new TNode;
	temp->key = key;
	temp->color = TNode::RED;
	temp->p = y;
	temp->left = temp->right = nil;

	if (y == nil) {
		root = temp;
	}
	else if(temp->key<y->key) {
		y->left = temp;
	}
	else {
		y->right = temp;
	}

	RBInsertFixup(temp);

}


void RBTree::RBInsertFixup(TNode* z) {

	while (z->p->color == TNode::RED) {//父节点是红色
		if (z->p == z->p->p->left) {//父节点是左孩子
			TNode* y = z->p->p->right;//将y指向叔叔节点

			if (y->color == TNode::RED) {//叔叔节点是红色(父红,叔红)
				//case 1 变换颜色
                //将叔叔节点和父节点都设为黑色
				y->color = TNode::BLACK;
				z->p->color = TNode::BLACK;
				y->p->color = TNode::RED;//将祖父节点设为红
				z = y->p;
			}
			else {//叔叔节点是黑色的或者为空(父红,叔黑)
                //z是右孩子,以父节点左旋
				if (z == z->p->right) {//case2
					z = z->p;
					RBLeftRoatate(z);
				}
                //case3,注意是先变色再旋转,而不是先旋转后变色,左旋之后节点变色,设置父亲为黑,祖父为红,
				z->p->color = TNode::BLACK;
				z->p->p->color = TNode::RED;
				RBRightRoatate(z->p->p);
			}
		}
		else {//父节点是右孩子

			TNode* y = z->p->p->left;

			if (y->color == TNode::RED) {
			
				y->color = TNode::BLACK;
				z->p->color = TNode::BLACK;
				y->p->color = TNode::RED;
				z = y->p;
			}
			else {
				if (z == z->p->left) {
					z = z->p;
					RBRightRoatate(z);
				}

				z->p->color = TNode::BLACK;
				z->p->p->color = TNode::RED;

				RBLeftRoatate(z->p->p);
			}

		}
	}

	if (root->color == TNode::RED) {
		blackHeight++;
	}

	root->color = TNode::BLACK;//设置根结点为黑色
}


void RBTree::printRBTree(TNode *x) {

	if (x->left != nil) {
		printRBTree(x->left);
	}
	cout<<x->key<<"\t"<<((x->color==TNode::BLACK)?"black":"red" )<<endl;

	if (x->right != nil) {

		printRBTree(x->right);
	}
		
}

int main()
{
	int key;
	RBTree * t = new RBTree;
	for(int i=1;i<=6;i++){
		cin>>key;
		t->RBInsertKey(key);
	}
	t->printRBTree(t->root);
	return 0;
}   

测试数据:

将关键字 41、38、31、12、19、8 连续地插入一棵初始化为空的红黑树

验证了算法的正确性 

有个大佬的博客比我更详细:http://xiaoyblog.sinaapp.com/archives/537

猜你喜欢

转载自blog.csdn.net/raylrnd/article/details/83832868