红黑树

1.红黑树简介
红黑树(Red Black Tree) 是一种自平衡二叉查找树,红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。
红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:
性质1. 节点是红色或黑色。
性质2. 根节点是黑色。
性质3 每个叶节点(NIL节点,空节点)是黑色的。
性质4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。
2.代码实现

#ifndef RBT_H
#define RBT_H
#include <iostream>
using namespace std;
enum Color
{
    RED,
    BLACK
};

template<typename K, typename V>
struct Node
{
    K key;
    V val;
    int N;
    Color color;
    Node<K, V>* left;
    Node<K, V>* right;

    Node()
    {
        this->left = NULL;
        this->right = NULL;
    }

    Node(K key, V val)
    {
        this->key = key;
        this->val = val;
        this->N = 1;
        this->color = RED;
        this->left = NULL;
        this->right = NULL;
    }
};

template<typename K, typename V>
class RBT
{
public:
    RBT();
    ~RBT();
    V Getval(const K& key) const;
    Node<K, V>* Insert(const K& key, const V& val);
    void Del(int arr[], int index, const K& key);
    bool contain(const K& key) const;
    int size() const;
    void clean();
    K minKey() const;
    K MaxKey() const;
    K CountLevel() const;
    void pretree() const;
    void midtree() const;
    void lasttree() const;
protected:
    Node<K, V>* root;
    Node<K, V>* Roleft(Node<K, V>* node);
    Node<K, V>* Roright(Node<K, V>* node);
    void filpNode(Node<K, V>* node);
    void ReFilpNode(Node<K, V>* node);
    Node<K, V>* fixNode(Node<K, V>* node);
    Node<K, V>* Insert(Node<K, V>* node, const K& key, const V& val);
    V Getval(Node<K, V>* node, const K& key) const;
    bool contain(Node<K, V>* node, const K& key) const;
    Node<K, V>* del(int arr[], int index, Node<K, V>* node, const K& key);
    void clean(Node<K, V>* node);
    int size(Node<K, V>* node) const;
    K minKey(Node<K, V>* node) const;
    K MaxKey(Node<K, V>* node) const;
    K CountLevel(Node<K, V>* node) const;
    bool isRed(Node<K, V>* node);
    void pretree(Node<K, V>* node) const;
    void midtree(Node<K, V>* node) const;
    void lasttree(Node<K, V>* node) const;
};

//构造 析构函数
template<typename K, typename V>
RBT<K, V>::RBT()
{
    this->root = NULL;
}

template<typename K, typename V>
RBT<K, V>::~RBT()
{
    clean(this->root);
}


/********************************************************************
函数名称:  isRed
函数参数: @node 节点指针
函数说明:  判断节点的颜色
返回值:    成功返回true 失败返回false
*********************************************************************/
template<typename K, typename V>
bool RBT<K, V>::isRed(Node<K, V>* node)
{
    if (node == NULL || node->color == BLACK)
        return false;
    else
        return true;
}
/********************************************************************
函数名称:   Insert
函数说明:   放入键值对<key,value> 若存在则将原有的value替换成新的value
返回值:     无
*********************************************************************/
template<typename K, typename V>
Node<K,V>* RBT<K, V>::Insert(const K& key, const V& val)
{
    return this->root = Insert(this->root, key, val);
}
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Insert(Node<K, V>* node, const K& key, const V& val)
{
    if (node == NULL)
        return new Node<K, V>(key, val);
    if (key > node->key)
        node->right = Insert(node->right, key, val);
    else if (key < node->key)
        node->left = Insert(node->left, key, val);
    else
        node->val = val;

    if (isRed(node->right) && !isRed(node->left))
        node = Roleft(node);
    if (node->left != NULL && isRed(node->left) && isRed(node->left->left))
        node = Roright(node);
    if (isRed(node->left) && isRed(node->right))
        filpNode(node);

    node->N = size(node->left) + size(node->right) + 1;
    return node;
}
/********************************************************************
函数名称:   Getval
函数说明:   获取指定key的value
返回值:     value
*********************************************************************/
template<typename K, typename V>
V RBT<K, V>::Getval(const K& key) const
{
    return Getval(this->root, key);
}
template<typename K, typename V>
V RBT<K, V>::Getval(Node<K, V>* node, const K& key) const
{
    if (node == NULL)
        return NULL;
    if (key > node->key)
        return Getval(node->right, key);
    else if (key < node->key)
        return Getval(node->left, key);
    else
        return node->val;
}
/********************************************************************
函数名称:   clean
函数说明:   清空表
返回值:    无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::clean()
{
    clean(this->root);
    this->root = NULL;
}
template<typename K, typename V>
void RBT<K, V>::clean(Node<K, V>* node)
{
    if (node == NULL)
        return;
    clean(node->left);
    clean(node->right);
    delete node;
}
/********************************************************************
函数名称:   size
函数说明:   无
返回值:     红黑树节点个数
*********************************************************************/
template<typename K, typename V>
int RBT<K, V>::size() const
{
    return size(this->root);
}
template<typename K, typename V>
int RBT<K, V>::size(Node<K, V>* node) const
{
    if (node == NULL)
        return 0;
    return size(node->right) + size(node->left) + 1;
}
/********************************************************************
函数名称:   Del
函数说明:   删除某个key
返回值:     无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::Del(int arr[], int index, const K& key)
{
    this->root = del(arr, index, this->root, key);
}
int Delete(int arr[],int n, int x)
{
    int p = 0, q = 0;  //用p和q两个变量  
    while (q<n)    //由q控制,扫描所有的元素  
    {
        if (arr[q] != x)  
        {
            arr[p] = arr[q];
            p++;
        }
        q++;
    }     
    return p;
}
template<typename K, typename V>
Node<K, V>* RBT<K, V>::del(int arr[],int index,Node<K, V>* node, const K& key)
{
    RBT<int, int>RBT1;
    if (node == NULL)
        return NULL;
    Delete(arr, index, key);
    for (int i = 0; i < index - 1; i++)
    {
        RBT1.Insert(arr[i], i);
    }
    swap(this->root, RBT1.root);
    root->color = BLACK;
    return this->root;
}

/********************************************************************
函数名称:   prevtree/midtree/lasttree
函数说明:   遍历
*********************************************************************/
template<typename K, typename V> //前序遍历
void RBT<K, V>::pretree() const
{
    pretree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::pretree(Node<K, V>* node) const
{
    if (node != NULL)
    {
        cout << node->key << '\t';
        if (node->color == BLACK)
        {
            cout << "黑色" << endl;
        }
        else
        {
            cout << "红色" << endl;
        }
        pretree(node->left);
        pretree(node->right);
    }
}

template<typename K, typename V> //中序遍历
void RBT<K, V>::midtree()const
{
    midtree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::midtree(Node<K, V>* node) const
{
    if (node != NULL)
    {
        midtree(node->left);
        cout << node->key << '\t';
        if (node->color == BLACK)
        {
            cout << "黑色" << endl;
        }
        else
        {
            cout << "红色" << endl;
        }
        midtree(node->right);
    }
}

template<typename K, typename V> //后序遍历
void RBT<K, V>::lasttree()const
{
    lasttree(this->root);
}
template<typename K, typename V>
void RBT<K, V>::lasttree(Node<K,V>* node) const
{
    if (node != NULL)
    {
        lasttree(node->left);
        lasttree(node->right);
        cout << node->key << '\t';
        if (node->color == BLACK)
        {
            cout << "黑色" << endl;
        }
        else
        {
            cout << "红色" << endl;
        }
    }
}

/********************************************************************
函数名称:   contain
函数说明:   是否包含key
返回值:     包含返回true 不包含返回false
*********************************************************************/
template<typename K, typename V>
bool RBT<K, V>::contain(const K& key) const
{
    return contain(this->root, key);
}
template<typename K, typename V>
bool RBT<K, V>::contain(Node<K, V>* node, const K& key) const
{
    if (node == NULL)
        return false;
    if (key > node->key)
        Getval(node->right, key);
    else if (key < node->key)
        Getval(node->left, key);
    else
        return true;
}
/********************************************************************
函数名称:  Roleft
函数参数: 需要旋转的节点指针
函数说明:  将右节点旋转到左边并设置为红色
返回值:    旋转后的树根指针
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Roleft(Node<K, V>* node)
{
    Node<K, V>* right = node->right;
    node->right = right->left;
    right->left = node;
    right->color = node->color;
    node->color = RED;
    node->N = size(node->left) + size(node->right) + 1;
    right->N = size(right->left) + size(right->right) + 1;
    return right;
}

/********************************************************************
函数名称:  Roright
函数参数: 需要旋转的节点指针
函数说明:  将左节点旋转到右边并设置为红色
返回值:    旋转后的树根指针
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::Roright(Node<K, V>* node)
{
    Node<K, V>* left = node->left;
    node->left = left->right;
    left->right = node;
    left->color = node->color;
    node->color = RED;
    node->N = size(node->left) + size(node->right) + 1;
    left->N = size(left->left) + size(left->right) + 1;
    return left;
}

/********************************************************************
函数名称:  flipNode
函数参数: 节点指针
函数说明:  将节点的左右子树的颜色变成黑色 同时节点颜色变成红色
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::filpNode(Node<K, V>* node)
{
    node->color = RED;
    node->left->color = BLACK;
    node->right->color = BLACK;
}
/********************************************************************
函数名称:  ReFilpNode
函数参数: @node 节点指针
函数说明:  反向翻转节点和子节点的颜色 将节点颜色变成黑色 子节点红色
返回值:    无
*********************************************************************/
template<typename K, typename V>
void RBT<K, V>::ReFilpNode(Node<K, V>* node)
{
    node->color = BLACK;
    node->left->color = RED;
    node->right->color = RED;
}

/********************************************************************
函数名称:  fixRedNode
函数参数: @node 节点指针
函数说明:  修复反向反转后节点 node->right->left 为红色的情况
返回值:
*********************************************************************/
template<typename K, typename V>
Node<K, V>* RBT<K, V>::fixNode(Node<K, V>* node)
{
    node->right = Roright(node->right);
    node = Roleft(node);
    return node;
}

/********************************************************************
函数名称:  minKey
函数参数: 无
函数说明:  返回表中最小的key
返回值:    key
*********************************************************************/
template<typename K, typename V>
K RBT<K, V>::minKey() const
{
    return minKey(this->root);
}
template<typename K, typename V>
K RBT<K, V>::minKey(Node<K, V>* node) const
{
    if (node->left == NULL)
        return node->key;
    else
        minKey(node->left);
}
/********************************************************************
函数名称:  MaxKey
函数参数: 无
函数说明:  返回红黑树中最大的key
返回值:    key
*********************************************************************/
template<typename K, typename V>
K RBT<K, V>::MaxKey() const
{
    return MaxKey(this->root);
}
template<typename K, typename V>
K RBT<K, V>::MaxKey(Node<K, V>* node) const
{
    if (node->right == NULL)
        return node->key;
    else
        MaxKey(node->right);
}
template<typename K, typename V>
K RBT<K, V>::CountLevel() const
{
    return CountLevel(this->root);
}
template<typename K, typename V>
K RBT<K, V>::CountLevel(Node<K, V>* node) const
{
    static int count = 0;
    if (node)
    {
        if (node->left == NULL&&node->right == NULL)
        ++count;
        CountLevel(node->left);
        CountLevel(node->right);
    }
    return count;
}
#endif

void test()
{
    RBT<int, int>RBT;
    int arr[11] = { 15, 6, 18, 3, 7, 17, 20, 2, 4, 13, 9 };
    //int arr[5] = { 3, 5, 6, 2, 4 };
    int index = sizeof(arr) / sizeof(arr[0]);
    Node<int, int>*ret = NULL;
    for (int i = 0; i < 11; i++)
    {
        ret = RBT.Insert(arr[i], i);
    }
    ret->color = BLACK;
    RBT.Del(arr, index, 3);
    RBT.midtree();
    cout << endl;
    cout << RBT.minKey() << endl;
    cout << RBT.MaxKey() << endl;
    cout << RBT.Getval(6) << endl;
    cout << RBT.size() << endl;
    cout << RBT.CountLevel() << endl;
    cout << RBT.contain(6) << endl;
    RBT.pretree();
    cout << endl;
    RBT.lasttree();
    cout << endl;
}
int main()
{
    test();
    system("pause");
    return 0;
}

这里写图片描述
这里写图片描述
这里写图片描述
3.红黑树和AVL树的比较
红黑树和AVL树都是高效的平衡二叉树, 增删查改的时间复杂度都是O(lg(N))
红黑树的不追求完全平衡, 保证最长路径不超过最短路径的2倍, 相对而言, 降低了旋转的要求, 所以性能会优于AVL树, 所以实际运用
中红黑树更多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值