红黑树

红黑树的性质:

(1)每个结点只能是红色或者黑色

(2) 根结点是黑色的

(3) 叶子结点是黑色的

(4) 如果一个结点是红色的,那么它的两个孩子都是黑色的

(5) 对于每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点




vim rbtree.h

#ifndef RBTREE_MODULE_H_
#define RBTREE_MODELE_H_

#include <iostream>
#include <stack>
#include <queue>
using std::cout;
using std::endl;
using std::stack;
using std::queue;

namespace rbtree
{

enum Color
{
        Red = 0,
        Black
};

template<typename T>
struct Node
{
        Color color;
        T  key;
        Node<T> *parent;
        Node<T> *left;
        Node<T> *right;
        Node(T k, Color c) : color(c), key(k), parent(NULL), left(NULL), right(NULL)
        { }
};

template<typename T>
struct StackNode
{
        Node<T> *data;
        bool    tag;
};


template<typename T>
class Rbtree
{
public:
        Rbtree() { root = NULL; }
        ~Rbtree() {  Rbtree_ClearNode(root); }

        void Left_Rotate(Node<T> *cur);
        void Right_Rotate(Node<T> *cur);

        void Rbtree_Insert(const T val);
        void Rbtree_Insert_Fixup(Node<T> *t);

        Node<T> * Rbtree_Search(const T val);
        Node<T> * Rbtree_Min(Node<T> *cur);
        Node<T> * Rbtree_Successor(Node<T> *cur);

        void Rbtree_Delete(const T val);
        void Rbtree_Delete_Fixup(Node<T> *t);

        void Rbtree_InOrder();
        void Rbtree_PreOrder();
        void Rbtree_PostOrder();
        void Rbtree_LayerOrder();

        void Rbtree_Visit(Node<T> *t);
        void Rbtree_ClearNode(Node<T> *t);
        int Rbtree_Height();
private:
        Node<T> *root;
};







template<typename T>
void Rbtree<T>::Left_Rotate(Node<T> *cur)
{
        if (NULL == cur)
                return ;
        Node<T> *tmp = cur->right;
        tmp->parent = cur->parent;
        cur->right = tmp->left;
        if (NULL != tmp->left)
                tmp->left->parent = cur;
        if (NULL == cur->parent)
                root = tmp;
        else if (cur->parent->left == cur)
                cur->parent->left = tmp;
        else
                cur->parent->right = tmp;
        tmp->left = cur;
        cur->parent = tmp;
}

template<typename T>
void Rbtree<T>::Right_Rotate(Node<T> *cur)
{
        if (NULL == cur)
                return ;
        Node<T> *tmp = cur->left;
        tmp->parent = cur->parent;
        cur->left = tmp->right;
        if (NULL != tmp->right)
                tmp->right->parent = cur;
        if (NULL == cur->parent)
                root = tmp;
        else if (cur->parent->left == cur)
                cur->parent->left = tmp;
        else
                cur->parent->right = tmp;
        tmp->right = cur;
        cur->parent = tmp;
}

template<typename T>
void Rbtree<T>::Rbtree_Insert(const T val)
{
        Node<T> *fresh = new Node<T>(val, Red);
        if (NULL == fresh)
        {
                cout << "Fail to allocate memory for " << val << endl;
                return ;
        }
        Node<T> *tmp = root;
        Node<T> *dst = NULL;
        while (NULL != tmp)
        {
                dst = tmp;
                if (val < tmp->key)
                        tmp = tmp->left;
                else
                        tmp = tmp->right;
        }
        if (NULL == dst) // empty tree before
                root = fresh;
        else
        {
                fresh->parent = dst;
                if (val < dst->key)
                        dst->left = fresh;
                else
                        dst->right = fresh;
        }
        Rbtree_Insert_Fixup(fresh);
}




template<typename T>
void Rbtree<T>::Rbtree_Insert_Fixup(Node<T> *t)
{
        Node<T> *uncle = NULL;
        while (NULL != t->parent && Red == t->parent->color && NULL != t->parent->parent)
        {
                // left tree
                if (t->parent == t->parent->parent->left)
                {
                        uncle = t->parent->parent->right;
                        // uncle is red
                        if (NULL != uncle && Red == uncle->color)
                        {
                                // handle the violation of property 4
                                t->parent->color = Black;
                                uncle->color = Black;
                                // keep property 5
                                t->parent->parent->color = Red;
                                // move up 2 layer
                                t = t->parent->parent;
                        }
                        else
                        {
                                // t is a right son
                                if (t == t->parent->right)
                                {
                                        t = t->parent;
                                        Left_Rotate(t);
                                }
                                // t is a left son
                                t->parent->color = Black;
                                t->parent->parent->color = Red;
                                Right_Rotate(t->parent->parent);
                        }

                }
                else  //right tree
                {
                        uncle = t->parent->parent->left;
                        if (NULL != uncle && Red == uncle->color)
                        {
                                t->parent->color = Black;
                                uncle->color = Black;
                                t->parent->parent->color = Red;
                                t = t->parent->parent;
                        }
                        else
                        {
                                if (t == t->parent->left)
                                {
                                        t = t->parent;
                                        Right_Rotate(t);
                                }
                                t->parent->color = Black;
                                t->parent->parent->color = Red;
                                Left_Rotate(t->parent->parent);
                        }

                }
        }
        root->color = Black;
}

template<typename T>
Node<T> * Rbtree<T>::Rbtree_Search(const T val)
{
        Node<T> * tmp = root;
        while (NULL != tmp && val != tmp->key)
        {
                if (val < tmp->key)
                        tmp = tmp->left;
                else
                        tmp = tmp->right;
        }

        return tmp;
}

template<typename T>
Node<T> * Rbtree<T>::Rbtree_Min(Node<T> *cur)
{
        if (NULL == cur)
                return NULL;

        while (NULL != cur->left)
                cur = cur->left;

        return cur;
}

template<typename T>
Node<T> * Rbtree<T>::Rbtree_Successor(Node<T> *cur)
{
        if (NULL != cur->right)
                return Rbtree_Min(cur->right);

        Node<T> *tmp = cur->parent;
        while (NULL != tmp && cur == tmp->right)
        {
                cur = tmp;
                tmp = tmp->parent;
        }

        return tmp;
}

template<typename T>
void Rbtree<T>::Rbtree_Delete(const T val)
{
        Node<T> *dst = Rbtree_Search(val);
        if (NULL == dst)
        {
                cout << "Can not find " << val << endl;
                return ;
        }
        cout << "delete " << val << endl;
        Node<T> *discard = NULL;
        Node<T> *dson = NULL;

        if (NULL == dst->left || NULL == dst->right)
                discard = dst;
        else
                discard = Rbtree_Successor(dst);

        if (NULL != discard->left)
                dson = discard->left;
        else
                dson = discard->right;

        if (NULL != dson)
                dson->parent = discard->parent;

        if (NULL == discard->parent)
                root = dson;
        else if (discard == discard->parent->left)
                discard->parent->left = dson;
        else
                discard->parent->right = dson;

        if (dst != discard)
                dst->key = discard->key;

        if (Black == discard->color && NULL != dson)
                Rbtree_Delete_Fixup(dson);

        delete discard;
        discard = NULL;
}



template<typename T>
void Rbtree<T>::Rbtree_Delete_Fixup(Node<T> *t)
{
        Node<T> *sibling = NULL;
        while (t != root && Black == t->color && NULL != t->parent)
        {
                if (t == t->parent->left)
                {
                        sibling = t->parent->right;
                        if (Red == sibling->color)
                        {
                                sibling->color = Black;
                                t->parent->color = Red;
                                Left_Rotate(t->parent);
                                sibling = t->parent->right;
                        }
                        else if (Black == sibling->left->color && Black == sibling->right->color)
                        {
                                sibling->color = Red;
                                t = t->parent;
                        }
                        else
                        {
                                if (Black == sibling->right->color) //left:red;right:black
                                {
                                        sibling->left->color = Black;
                                        sibling->color = Red;
                                        Right_Rotate(sibling);
                                        sibling = t->parent->right;
                                }
                                sibling->color = t->parent->color;
                                t->parent->color = Black;
                                sibling->right->color = Black;
                                Left_Rotate(t->parent);
                                t = root;
                        }
                }
                else
                {
                        sibling = t->parent->left;
                        if (Red == sibling->color) //sibling:red
                        {
                                sibling->color = Black;
                                t->parent->color = Red;
                                Right_Rotate(t->parent);
                                sibling = t->parent->left;
                        }
                        else if (Black == sibling->left->color && Black == sibling->right->color)
                        {
                                sibling->color = Red;
                                t = t->parent;
                        }
                        else
                        {
                                if (Black == sibling->left->color) //left:red;right:black
                                {
                                        sibling->right->color = Black;
                                        sibling->color = Red;
                                        Left_Rotate(sibling);
                                        sibling = t->parent->left;
                                }
                                sibling->color = t->parent->color;
                                t->parent->color = Black;
                                sibling->left->color = Black;
                                Right_Rotate(t->parent);
                                t = root;
                        }
                }

        }
        t->color = Black;
}

template<typename T>
void Rbtree<T>::Rbtree_InOrder()
{
        Node<T> *tmp = root;
        stack<Node<T> *> st;

        while (NULL != tmp || !st.empty())
        {
                while (NULL != tmp)
                {
                        st.push(tmp);
                        tmp = tmp->left;
                }

                tmp = st.top();
                Rbtree_Visit(tmp);
                st.pop();
                tmp = tmp->right;
        }
}


template<typename T>
void Rbtree<T>::Rbtree_PreOrder()
{
        Node<T> *tmp = root;
        stack<Node<T> *> st;
        while (NULL != tmp || !st.empty())
        {
                while (NULL != tmp)
                {
                        Rbtree_Visit(tmp);
                        st.push(tmp);
                        tmp = tmp->left;
                }

                tmp = st.top();
                st.pop();
                tmp = tmp->right;
        }
}

template<typename T>
void Rbtree<T>::Rbtree_PostOrder()
{
        StackNode<T> node;
        stack<StackNode<T> > st;
        Node<T> *tmp = root;

        do{
                while (NULL != tmp)
                {
                        node.data = tmp;
                        node.tag = false;
                        st.push(node);
                        tmp = tmp->left;
                }

                while (!st.empty() && st.top().tag)
                {
                        tmp = st.top().data;
                        st.pop();
                        Rbtree_Visit(tmp);
                }

                if (!st.empty())
                {
                        st.top().tag = true;
                        tmp = st.top().data->right;
                }

        } while(!st.empty());
}

template<typename T>
void Rbtree<T>::Rbtree_LayerOrder()
{
        Node<T> *tmp = root;
        if (NULL == tmp)
                return ;
        queue<Node<T> *> qu;
        qu.push(tmp);

        while (!qu.empty())
        {
                //Rbtree_Visit(tmp);
                tmp = qu.front();
                qu.pop();
                if (tmp->left)
                        qu.push(tmp->left);
                if (tmp->right)
                        qu.push(tmp->right);
                Rbtree_Visit(tmp);

        }
}

template<typename T>
void Rbtree<T>::Rbtree_Visit(Node<T> *t)
{
        if (NULL != t)
                cout << t->key << " , " << t->color << endl;

}

template<typename T>
void Rbtree<T>::Rbtree_ClearNode(Node<T> *t)
{
        if (NULL != t)
        {
                Rbtree_ClearNode(t->left);
                Rbtree_ClearNode(t->right);

                cout << "clear node = " << t->key << endl;
                delete t;
                t = NULL;
        }
}

template<typename T>
int Rbtree<T>::Rbtree_Height()
{
        Node<T> *tmp = root;
        if (NULL == tmp)
                return 0;
        int height = 0;
        queue<Node<T> *> qu;
        qu.push(tmp);
        qu.push(NULL);
        ++height;

        while (!qu.empty())
        {
                tmp = qu.front();
                qu.pop();
                if (tmp)
                {
                        if (NULL != tmp->left)
                                qu.push(tmp->left);
                        if (NULL != tmp->right)
                                qu.push(tmp->right);
                }
                else if (!qu.empty())
                {
                        ++height;
                        qu.push(NULL);
                }
        }

        return height;
}


}

#endif
                                                          
main.cpp

#include "rbtree.h"
using namespace::rbtree;



int main()
{
        Rbtree<int> rbt;
        int arr[11] = {4, 2, 1, 3, 8, 7, 5, 6, 10, 9, 11};
        for (int i = 0; i < 11; ++i)
                rbt.Rbtree_Insert(arr[i]);
        rbt.Rbtree_InOrder();
        rbt.Rbtree_Delete(3);
        rbt.Rbtree_InOrder();
        cout << "PostOrder" << endl;
        rbt.Rbtree_PostOrder();
        cout << "LayerOrder" << endl;
        rbt.Rbtree_LayerOrder();
        cout << "Height = " << rbt.Rbtree_Height() << endl;

        return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值