紅黑樹的C++實現

C++類的基本結構:

1. 紅黑樹節點的數據結構

class Item{
public:
	Item(const int &key):
		key(key),color(true),left(nullptr),right(nullptr),parent(nullptr){}
	Item():
		key(0),color(false),left(nullptr),right(nullptr),parent(nullptr){}
	//up sentence use to generate a null item
	bool color;//true represent red,false represent black
	int key;
	Item *left,*right,*parent;
};

2. 紅黑樹類:

class RBTree{
public:
	RBTree():root(nulptr){
	}
	void left_rotate(Item *x);
	void right_rotate(Item *x);
	Item* RBInsert(Item *z);
	Item* RBDelete(Item *z);
	Item* TreeMinimum(Item *z);
	Item* TreeSuccessor(Item* z);
	//void Search(Item* item);
	void PrintTree();
	~RBTree(){
		destory(root);
	}
private:
	Item *root;
	static Item *nulptr;
	void destory(Item* item);
	void Print(Item* item);
	void RB_Insert_Fixup(Item *z);
	void RBDeleteFixup(Item *z);
};
Item* RBTree::nulptr = new Item(); // 空節點的,(算法導論裏面的葉節點。)

然後,就是類裏面函數的實現了。

左旋轉:

void RBTree::left_rotate(Item *x){
	Item *y = x->right;
	x->right = y->left;
	if(y->left != nulptr){
		y->left->parent = x;
	}
	y->parent = x->parent;
	if(x->parent==nulptr){
		root = y;
	}else if(x == x->parent->left)
	{
		x->parent->left = y;
	}else{
		x->parent->right = y;
	}
	y->left = x;
	x->parent = y;
}

右旋轉:

void RBTree::right_rotate(Item *x){
	Item *y = x->left;
	x->left = y->right;
	if(y->right != nulptr){
		y->right->parent = x;
	}
	y->parent = x->parent;
	if(x->parent == nulptr){
		root = y;
	}else if(x->parent->left == x){
		x->parent->left = y;
	}else{
		x->parent->right = y;
	}
	y->right = x;
	x->parent = y;
}

插入函數:

Item* RBTree::RBInsert(Item *z){
	Item *y = nulptr;
	Item *x = root;

	while(x!=nulptr){
		y = x;
		if(x->key > z->key){
			x = x->left;
		}else if(x->key < z->key){
			x = x->right;
		}else{
			return x;
		}
	}
	z->parent = y;
	if(y==nulptr){
		root = z;
		root->parent = nulptr;
	}else if(y->key > z->key){
		y->left = z;
	}else{
		y->right = z;
	}
	z->left = nulptr;
	z->right = nulptr;
	z->color = true;
	RB_Insert_Fixup(z);
}

插入之後,節點顏色修改函數:

void RBTree::RB_Insert_Fixup(Item *z){
	while(z->parent->color){
		if(z->parent == z->parent->parent->left){ //if z's parent is left of z's grad.
			if(z->parent->parent->right->color){ //if z's uncle's color is red ---case 1
				z->parent->color = false;
				z->parent->parent->right->color = false;
				z->parent->parent->color = true;
				z = z->parent->parent;
				continue;
			}
			else if(z == z->parent->right){ //if z is right of parent,
				z = z->parent;				//and uncle's color is black --case2
				left_rotate(z);			    //case2 we need change it to case3
			}
			//if z is left of parent,and uncle's color is black --case 3
			z->parent->color = false;
			z->parent->parent->color = true;
			right_rotate(z->parent->parent);
		}else{  //if z's parent is right of z's grad.
			if(z->parent->parent->left->color){ //if z's uncle's color is red --case 1
				z->parent->color = false;
				z->parent->parent->left->color = false;
				z->parent->parent->color = true;
				z = z->parent->parent;
				continue;
			}else if(z == z->parent->left){ //if z is left of parent ,
				z = z->parent;				// and uncle's color is black --case 2
				right_rotate(z);			// case 2 we need change it to case 3.
			}
			//if z is right of parent ,and uncle's color is black --case 3
			z->parent->color = false;
			z->parent->parent->color = true;
			left_rotate(z->parent->parent);
		}
	}
	root->color = false;
}

獲取子樹的最小節點:

Item* RBTree::TreeMinimum(Item *z){
	while(z->left != nulptr){
		z = z->left;
	}
	return z;
}

獲取給定節點的後繼節點:

Item* RBTree::TreeSuccessor(Item *z){
	if(z->right!=nulptr){
		return TreeMinimum(z);
	}
	Item* x = z;
	Item* y = z->parent;
	while(y!=nulptr && x == y->right){
		x = y;
		y = y->parent;
	}
	return y;
}

刪除指定節點的函數:(節點刪除的時候有返回所刪除節點的指針,使用完應該釋放這個節點的空間)

Item* RBTree::RBDelete(Item* z){
	Item* y;
	if(z->left == nulptr || z->right == nulptr){
		y = z;
	}else{
		y = TreeSuccessor(z);
	}
	Item* x;
	if(y->left != nulptr)
		x = y->left;
	else
		x = y->right;
	x->parent = y->parent;
	if(y->parent == nulptr)
		root = x;
	else if(y == y->parent->left)
		y->parent->left = x;
	else
		y->parent->right = x;

	if(y!=z){
		z->key = y->key;
	}
	if(!y->color)
		RBDeleteFixup(x);
	return y;
}

刪除節點之後,顏色的調整:

void RBTree::RBDeleteFixup(Item* z){
	while(z!=root && !(z->color)){
		Item* w;
		if(z == z->parent->left){ //if z is left of its parent.
			w = z->parent->right;
			if(w->color){				//if z's brother's color is red, --case 1
				w->color = false;		//we need change this case to case 2,3 or 4.
				z->parent->color = true;// we through left rotate z's parent.
				left_rotate(z->parent);
				w = z->parent->right;
			}
			if(!(w->left->color) && !(w->right->color)){// if w's two children are black--case 2
				w->color = true;						
				z = z->parent;
				continue;
			}else if(!w->right->color){//if w's right child is black and left child is red---case 3
				w->left->color = false;
				w->color = true;
				right_rotate(w);
				w = z->parent->right;
			}
			w->color = z->parent->color;//if w's right child is red -- case 4
			z->parent->color = false;
			w->right->color = false;
			left_rotate(z->parent);
			z = root;
		}else{ // if z is right of its parent.
			w = z->parent->left;
			if(w->color){
				w->color = false;
				z->parent->color = true;
				right_rotate(z->parent);
				w = z->parent->left;
			}
			if(!(w->left->color) && !(w->right->color)){// if w's two children are black--case 2
				w->color = true;						
				z = z->parent;
				continue;
			}else if(!w->right->color){//if w's right child is black and left child is red---case 3
				w->left->color = false;
				w->color = true;
				right_rotate(w);
				w = z->parent->left;
			}
			w->color = z->parent->color;//if w's right child is red -- case 4
			z->parent->color = false;
			w->left->color = false;
			right_rotate(z->parent);
			z = root;
		}
	}
}

点赞