模板--红黑树(C++实现)

一、结点类与红黑树类:

(一)结点类基本数据成员:

1.左右子结点指针域

2.父结点指针域,方便回访父结点

3.有序 前驱 / 后继 指针域,迭代访问元素,提供一种顺序存储的假象

4.结点颜色,利用红黑规则,保持树的平衡。

(二)结点类的基本成员函数:

两个重载的构造函数,构造红色的新结点

(三)红黑树类基本数据成员:

1.头结点:保存一个据点,用来维系根节点与公用空结点

2.根结点:是红黑树的起始位置

3.空结点:作为所有空指针域的指向,一棵树只有一个

4.全局前驱、后继结点:用来使红黑树线索化,变得可迭代

(四)红黑树类基本成员函数(面向内部):

1.中序递归构造线索

2.结点左旋、右旋操作

3.插入后修正红黑树

4.移除后修正红黑树

5.移植(替换)结点

6.子树最大、最下结点

(五)红黑树类基本成员函数(面向用户):

1.构造函数,构造空树

2.空树判断

3.插入元素

4.移除元素

5.搜索元素

6.获取起始、终止迭代器、元素最大值、元素最小值

7.递归遍历

8.迭代器遍历

博客园同步更新

头文件:

#ifndef _RBtree
#define _RBtree

#include <iostream>
using namespace std;
template<typename T>
class RBTree;
enum Color{RED=0,BLACK=1};
template<typename T>
class RBnode{
	friend class RBTree<T>;
	public:
	    typedef RBnode<T>* rb_iterator;
    private:
		typedef RBnode<T>* Nodeptr;
	public:
		Nodeptr left,right,parent;
		Nodeptr prior,next;
		Color color;
    public:
        T val;
	public://新结点都是红结点
		RBnode(T value){left=right=parent=this;val=value;color=RED;}
		RBnode(T value, Nodeptr l, Nodeptr r):val(value),left(l),right(r){parent=this,color=RED;}
};
template<typename T>
class RBTree{
	friend class RBnode<T>;
	private:
        typedef RBnode<T>* Nodeptr;
    public:
        typedef RBnode<T>* rb_iterator;
	private:
		Nodeptr header;
		Nodeptr root;
		Nodeptr nlnode;
		Nodeptr _prior;
		Nodeptr _next;
	public:
		RBTree(){
			header=new RBnode<T>(0);
			nlnode=new RBnode<T>(-1);
			nlnode->color = header->color = BLACK;
			root=nlnode;
			root->parent=header;
			root->left=root->right=nlnode;
			header->left=nlnode;
			header->right=root;
			nlnode->parent=nlnode;
			header->next = nlnode;
			header->prior = nlnode;
		}
	public:
		bool isEmpyty();
		void Insert(T x);
		void Insert(Nodeptr);
		bool remove(T x);
		bool remove(Nodeptr x);
		Nodeptr search(T x);
		T getMax();
		T getMin();
		rb_iterator begin(){return header->next;}
		rb_iterator end(){return header;}
		void inorderWalk(Nodeptr p) const ;
		void LORvisit();
		void Iterator_visit(rb_iterator start, rb_iterator over) {
		    rb_iterator temp = start;
            while(temp != over){
                cout << temp->val << ' ';
                temp = temp->next;
            }
		}
    private:
        void LOR();
		void LOR(Nodeptr c);
		void LeftRotate(Nodeptr x);
		void RightRotate(Nodeptr x);
		void Fix_up_insert(Nodeptr x);
		void Fix_up_remove(Nodeptr x);
		void Transplante(Nodeptr old, Nodeptr neo);
		Nodeptr BranchMax(Nodeptr x);
		Nodeptr BranchMin(Nodeptr x);
		void LORvisit(Nodeptr c);
};
template<typename T>
void RBTree<T>::LOR(){
    _prior = _next = header;
    LOR(root);
    _next->next=header;
    header->prior=_next;
}
template<typename T>
void RBTree<T>::LORvisit(){
    LORvisit(root);
    cout << endl;
}
template<typename T>
void RBTree<T>::LOR(Nodeptr c){
    if(c->left != nlnode){
        LOR(c->left);
    }
    _prior = _next;
    _next = c;
    _prior->next=_next;
    _next->prior=_prior;
    if(c->right != nlnode){
        LOR(c->right);
    }
}
template<typename T>
void RBTree<T>::LORvisit(Nodeptr c){
    if(c->left != nlnode){
        LORvisit(c->left);
    }
    cout << c->val << ' ';
    if(c->right != nlnode){
        LORvisit(c->right);
    }
}
template<typename T>
bool RBTree<T>::isEmpyty(){
	return root == nlnode;
}
template<typename T>
void RBTree<T>::Insert(T x){
    Nodeptr n=new RBnode<T>(x, nlnode, nlnode);
    Insert(n);
}
template<typename T>
void RBTree<T>::Insert(Nodeptr x){
    Nodeptr first,second;
    first = second = root;
    if(root == nlnode){
        root = x;
        header->right = x;
        x->parent = header;
        x->color = BLACK;
        return;
    }
    while(first!=nlnode){
        second = first;
        if(first->val > x->val){
            first = first->left;
        }else if(first->val < x->val){
            first = first->right;
        }else{
            return ;
        }
    }
    x->parent = second;
    if(second->val > x->val){
        second->left = x;
    }else{
        second->right = x;
    }
    Fix_up_insert(x);
    LOR();
}
template<typename T>
void RBTree<T>::LeftRotate(Nodeptr x){
    if(x->right == nlnode)//无右子树不可左旋,避免错误操作将树旋空
        return;
    Nodeptr x_r=x->right;
    x->right = x_r->left;
    if(x_r->left!=nlnode)//避免破坏空节点的特性:父结点指向自身
        x_r->left->parent = x;
    x_r->parent = x->parent;
    if(x_r->parent == header){//根节点
        root = x_r;
    }else if(x->parent->left == x){//更新父结点
        x->parent->left = x_r;
    }else if(x->parent->right == x){
        x->parent->right = x_r;
    }
    x_r->left = x;
    x->parent = x_r;
}
template<typename T>
void RBTree<T>::RightRotate(Nodeptr x){
    if(x->left == nlnode)//无右子树不可左旋,避免错误操作将树旋空
        return;
    Nodeptr x_l=x->left;
    x->left = x_l->right;
    if(x_l->right!=nlnode)//避免破坏空节点的特性:父结点指向自身
        x_l->right->parent = x;
    x_l->parent = x->parent;
    if(x_l->parent == header){//根节点
        root = x_l;
    }else if(x->parent->right == x){//更新父结点
        x->parent->right = x_l;
    }else if(x->parent->left == x){
        x->parent->left = x_l;
    }
    x_l->right = x;
    x->parent = x_l;
}
template<typename T>
void RBTree<T>::Fix_up_insert(Nodeptr x){
    while(x->parent->color==RED){//首先满足没有连续的红色结点
        if(x->parent == x->parent->parent->left){
            if(x->parent->parent->right->color == RED){//case 1: son --red,dad&dad's brother --red
                x->parent->parent->right->color = x->parent->color = BLACK;
                x->parent->parent->color = RED;
                x = x->parent->parent;
            }
            else{
                if(x == x->parent->right){//case 2:inner side,son --red,dad --red
                    x = x->parent;
                    LeftRotate(x);
                }
                x->parent->parent->color = RED;//case 3:outer side,son --red,dad --red
                x->parent->color = BLACK;
                x = x->parent;
                RightRotate(x->parent->parent);
            }
        }
        else{
            if(x->parent->parent->left->color == RED){//case 1: son --red,dad&dad's brother --red
                x->parent->parent->left->color = x->parent->color = BLACK;
                x->parent->parent->color = RED;
                x = x->parent->parent;
            }
            else{
                if(x == x->parent->left){//case 2:inner side,son --red,dad --red
                    x = x->parent;
                    LeftRotate(x);
                }
                x->parent->parent->color = RED;//case 3:outer side,son --red,dad --red
                x->parent->color = BLACK;
                x = x->parent;
                RightRotate(x->parent->parent);
            }
        }
    }
    root->color=BLACK;
}
template<typename T>
RBnode<T>* RBTree<T>::search(T x){
    Nodeptr temp = root;
    while(temp!=nlnode){
        if(temp->val > x){
            temp = temp->left;
        }else if(temp->val < x){
            temp = temp->right;
        }else{
            return temp;
        }
    }
    return nlnode;
}
template<typename T>
bool RBTree<T>::remove(T x){
    Nodeptr target = search(x);
    if(target == nlnode){
        LOR();
        return false;}
    return remove(target);
}
template<typename T>
bool RBTree<T>::remove(Nodeptr x){
    Nodeptr a = x;
    Nodeptr b = nlnode;
    Color a_OriCo = a->color;
    if(x->left==nlnode){//case 1:with one kid or no one
        b = x->right;
        Transplante(x, x->right);
    }else if(x->right==nlnode){
        b = x->left;
        Transplante(x, x->left);
    }else{
        Nodeptr a=BranchMin(x->right);
        a_OriCo = a->color;
        b = a->right;
        if(a->parent == x){//case 2:replace node is son of x
            b->parent = a;//case nlnode
        }else{
            Transplante(a, a->right);//a break away from there
            a->right = x->right;
            a->right->parent = a;
        }
        Transplante(x, a);//用新结点分支替换旧结点分支
        a->left = x->left;
        a->left->parent = a;
        a->color = x->color;
    }
    delete x;
    if(a_OriCo == BLACK){//case 3:违背红黑规则,路径黑结点数不同
        Fix_up_remove(b);
    }
    LOR();
}
template<typename T>
void RBTree<T>::Transplante(Nodeptr old, Nodeptr neo){
    if(old->parent == header){
        header->right = neo;
        root = neo;
    }else if(old->parent->left == old){
        old->parent->left = neo;
    }else if(old->parent->right == old){
        old->parent->right = neo;
    }
    neo->parent = old->parent;
}
template<typename T>
RBnode<T>* RBTree<T>::BranchMax(Nodeptr x){
    if(x == nlnode)
        return x;
    Nodeptr temp=x;
    while(temp->right!=nlnode){
        temp=temp->right;
    }
    return temp;
}
template<typename T>
RBnode<T>* RBTree<T>::BranchMin(Nodeptr x){
    if(x == nlnode)
        return x;
    Nodeptr temp=x;
    while(temp->left!=nlnode){
        temp=temp->left;
    }
    return temp;
}
template<typename T>
void RBTree<T>::Fix_up_remove(Nodeptr x){
    Nodeptr z = nlnode;
    while(x!=root&&x->color==BLACK){
        if(x == x->parent->left){
            z=x->parent->right;
            if(z->color == RED){//case 1:x's brather --red
                z->color=BLACK;
                x->parent->color = RED;
                LeftRotate(x->parent);//利用红色来保持黑一致
                z = x->parent->right;//update x's brother
            }//case 2:x&x's brother sons color same
            if(z->left->color==BLACK && z->right->color==BLACK){
                z->color = RED;//保持与x颜色一致,因为是兄弟结点
                x = x->parent;//向上调整
            }
            else {
                if(z->right->color==BLACK) {//z:x's brother
                    z->color = RED;//case 3:z left--red,right--black
                    z->left->color = BLACK;
                    RightRotate(z);
                    z = x->parent->right;
                }
                //case 4:adjust x and z
                //将树平衡高度,保持了原父结点位置的颜色
                z->color = x->parent->color;
                x->parent->color = BLACK;
                z->right->color = BLACK;
                LeftRotate(x->parent);
                break;
            }
        }
        else {
            z=x->parent->left;
            if(z->color == RED){//case 1:x's brather --red
                z->color=BLACK;
                x->parent->color = RED;
                this->RightRotate(x->parent);//利用红色来保持黑一致
                z = x->parent->left;//update x's brother
            }//case 2:x&x's brother sons color same
            if(z->right->color==BLACK && z->left->color==BLACK){
                z->color = RED;//保持与x颜色一致,因为是兄弟结点
                x = x->parent;//向上调整
            }
            else {
                if(z->left->color==BLACK) {//z:x's brother
                    z->color = RED;//case 3:z left--red,right--black
                    z->right->color = BLACK;
                    LeftRotate(z);
                    z = x->parent->left;
                }
                //case 4:adjust x and z
                //将树平衡高度,保持了原父结点位置的颜色
                z->color = x->parent->color;
                x->parent->color = BLACK;
                z->left->color = BLACK;
                RightRotate(x->parent);
                break;
            }
        }
    }
    root->color = BLACK;//保持根为黑
}
template<typename T>
T RBTree<T>::getMax(){
    return header->prior->val;
}
template<typename T>
T RBTree<T>::getMin(){
    return header->next->val;
}


#endif

测试代码:

#include <iostream>
#include <stdlib.h>
#include "templateRBTree.h"
using namespace std;

int main()
{
	RBTree<int> rb;
	for(int i=0;i < 10;++i)
        rb.Insert(rand()%20);
    cout << "create RBTree: ";
    rb.LORvisit();
    RBTree<int>::rb_iterator itr=rb.begin();
    cout << "visit tree by iterator: " << endl;
    rb.Iterator_visit(itr, rb.end());
    cout << endl;
    cout << "the max of tree: " << rb.getMax() << endl;
    cout << "the min of tree: " << rb.getMin() << endl;
    for(int i=0;i<10;++i)
        rb.remove(i);
    cout << "remove x<10: ";
    rb.LORvisit();
    cout << "the max of tree: " << rb.getMax() << endl;
    cout << "the min of tree: " << rb.getMin() << endl;
    itr=rb.begin();
    cout << "visit tree by iterator: " << endl;
    rb.Iterator_visit(itr, rb.end());
	return 0;
}

 结果:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼卡尼卡尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值