RB-tree 红黑树

来源:互联网 发布:万网解析域名 编辑:程序博客网 时间:2024/06/06 08:24

除AVL树外,还有RBtree也是经常用到的平衡二叉搜索树
RBtree必须满足以下四条规则:
1.每个节点不是红色就是黑色
2.根节点为黑色
3.如果一个节点是红色,则它的 子节点是黑色的(即没有连续的红节点)
4.任一节点至NULL(树尾端)的任何路径,所含黑节点数必须相同
那AVL和RBtree有什么区别
AVltree 是严格平衡的二叉搜索树,其复杂度接近lgN,旋转多,维护起来麻烦,但是更加直观
RBree 是近似平衡的二叉搜索树,其复杂度一定小于2*(LgN),但是曾有人做过大量试验证明,红黑树的效率仍能达到lgN,旋转则较少,维护起来简单,今后项目什么的一定会优先RBtree,其比较抽象
插入操作
注意:cur为当前节点 P为父节点 g为祖父节点 u为父亲的兄弟节点即叔叔节点
状况1:该树为空树,直接插入根结点的位置,违反性质1,把节点颜色有红改为黑即可。
状况2:插入节点N的父节点P为黑色,不违反任何性质,无需做任何修改。
接下来是真正需要调整的状况了
状况3:当cur为红,P为红,g为黑,u存在且为红
先将p,u变为黑色,g改成红,然后把cur给g,继续向上搜索
这里写图片描述
状况4: cur为红,P为红,g为黑,u不存在/u为黑(cur为p的左节点)
这里写图片描述
状态5:cur为红,P为红,g为黑,u不存在/u为黑(cur为p的右节点)
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转,则转换成了情况2
这里写图片描述
删除操作
状况1:cur的兄弟b是红色的。
这里写图片描述
情况2:cur的兄弟b是黑色的,且cur的俩个孩子都是黑色的。
b变为红色后经过b节点的路径的黑节点数目也减少了1,那个从P出发到其叶子节点到所有路径所包含的黑节点数目相等了。但是这个数目比之前少了1,因为左右子树中的黑节点数目都减少了。P是他父节点g的一个孩子,那么由g到其叶子节点的黑节点数目就不相等了,所以说没有结束,需把P当做新的起始点开始向上检索。
这里写图片描述
情形3:P为红(S一定为黑),S的孩子们都为黑。
这里写图片描述
情形4:P任意色,b为黑,cur是P的左孩子,b的右孩子bR为红,b的左孩子任意(或者是cur是P的右孩子,b的左孩子为红,b的右孩子任意)。
P、b旋转有变色,等于给cur这边加了一个黑节点,P位置(是位置而不是P)的颜色不变,b这边少了一个黑节点;bR有红变黑,b这边又增加了一个黑节点;这样一来又恢复了平衡
这里写图片描述
情形5:P任意色,b为黑,cur是P的左孩子,b的左孩子bL为红,b的右孩子bR为黑(或者cur是P的右孩子,b的右孩子为红,b的左孩子为黑)。
这如果你按情形4的操作的话,由于bR本来就是黑色,无法弥补由于P、b的变换(旋转)给b这边造成的损失!所以没先对b、SL进行变换之后就变为情形4的情况了
这里写图片描述

#pragma once#include<stdio.h>#include<iostream>using namespace std;enum Color{    RED,    BLACK,};template<class K, class V>struct RBTreeNode{    RBTreeNode<K, V>* _left;    RBTreeNode<K, V>* _right;    RBTreeNode<K, V>* _parent;    K _key;    V _value;    Color _col;    RBTreeNode(const K& key, const V& value)        :_left(NULL)        , _right(NULL)        , _parent(NULL)        , _key(key)        , _value(value)        , _col(RED)    {}};template<class K,class V>class RBTree{    typedef RBTreeNode<K,V> Node;public:    RBTree()        :_root(NULL)    {}    bool Insert(const K& key,const V& value)    {        if (_root == NULL)        {            _root = new Node(key,value);            _root->_col = BLACK;            return true;        }        Node* parent = NULL;        Node* cur = _root;        while (cur)        {            if (cur->_key > key)            {                parent = cur;                cur = cur->_left;            }            else if (cur->_key < key)            {                parent = cur;                cur = cur->_right;            }            else            {                return false;            }        }        //找到插入位置        cur = new Node(key, value);        if (parent->_key < key)        {            parent->_right = cur;            cur->_parent = parent;        }        else        {            parent->_left = cur;            cur->_parent = parent;        }        while (parent&&parent->_col == RED)        {            Node* grandparent = parent->_parent;            if (parent == grandparent->_left)            {                Node* uncle = grandparent->_right;                if (uncle&&uncle->_col == RED)                {                    parent->_col = BLACK;                    uncle->_col = BLACK;                    grandparent->_col = RED;                    cur = grandparent;                    parent = cur->_parent;                }                else //uncle不存在,或uncle为黑色                {                    if (cur == parent->_right)                    {                        RotateL(parent);                        swap(parent,cur);                    }                    RotateR(grandparent);                    parent->_col = BLACK;                    grandparent->_col = RED;                    break;                }            }            else//parent == grandparent->_right            {                Node* uncle = grandparent->_left;                if (uncle&&uncle->_col == RED)                {                    parent->_col = BLACK;                    uncle->_col = BLACK;                    grandparent->_col = RED;                }                else//uncle不存在或者为黑色                {                    if (cur == parent->_left)                    {                        RotateR(parent);                        swap(parent, cur);                    }                    RotateL(grandparent);                    parent->_col = BLACK;                    grandparent->_col = RED;                    break;                }            }        }        _root->_col = BLACK;        return true;    }    void RotateL(Node* parent)    {        Node* subR = parent->_right;        Node* subRL = subR->_left;        parent->_right = subRL;        if (subRL)        {            subRL->_parent = parent;        }        subR->_left = parent;        Node* parentparent = parent->_parent;        parent->_parent = subR;        if (parentparent==NULL)        {            _root = subR;        }        else        {            if (parent == parentparent->_left)            {                parentparent->_left = subR;                subR->_parent = parentparent;            }            else            {                parentparent->_right = subR;                subR->_parent = parentparent;            }        }    }    void RotateR(Node* parent)    {        Node* subL = parent->_left;        Node* subLR = subL->_right;        parent->_left = subLR;        if (subLR)        {            subLR->_parent = parent;        }        subL->_right = parent;        Node* parentparent = parent->_parent;        parent->_parent = subL;        if (parentparent == NULL)        {            _root = subL;            _root->_parent = NULL;        }        else        {            if (parent == parentparent->_left)            {                parentparent->_left = subL;                subL->_parent = parentparent;            }            else            {                parentparent->_right = subL;                subL->_parent = parentparent;            }        }    }    void InOrder()    {        _InOrder(_root);        cout << endl;    }    void _InOrder(Node* root)    {        if (root == NULL)            return;        _InOrder(root->_left);        cout<<root->_key<<" ";        _InOrder(root->_right);    }    bool IsBalance()    {        if (_root == NULL)        {            return true;        }        if (_root&&_root->_col==RED)        {            return false;        }        int BlackNum = 0;        Node* left = _root;        while (left)        {            if (left->_col == BLACK)            {                ++BlackNum;            }            left = left->_left;        }        int num = 0;        return _IsBalance(_root, num, BlackNum);    }    bool _IsBalance(Node* root, int num, const int blackNum)    {        if (root == NULL)        {            return true;        }        if (root->_col == RED&&root->_parent->_col == RED)        {            cout<<"存在连续的红节点"<<root->_key<<endl;            return false;        }        if (root->_col == BLACK)        {            ++num;        }        // num 是根节点到当前节点黑色节点的数量        if (root->_left == NULL && root->_right == NULL)        {            if (num != blackNum)            {                //cout<<"黑色节点的数量不相等"<<root->_key<<endl;                return false;            }            else            {                return true;            }        }        return _IsBalance(root->_left, num, blackNum)            && _IsBalance(root->_right, num, blackNum);    }private:    Node* _root;};void TestRBTree(){        RBTree<int, int> t;        int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15};        //int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14};        for (size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i)        {            t.Insert(a[i], i);        }        t.InOrder();        cout<<"IsBalance?"<<t.IsBalance()<<endl;}
原创粉丝点击