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;
}
}
}