红黑树

来源:互联网 发布:道亨软件下载 编辑:程序博客网 时间:2024/06/06 20:10

红黑树:红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点上的简单路径来约束,红黑树保证最长路径不超过最短路径的两倍,因而近视平衡。
性质:
1. 每个结点不是红色就是黑色
2. 根节点是黑色的
3. 如果一个根节点是红色的,则它的两个叶子结点是黑色的(没有两个连续
的红色结点)
4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相
同数目的黑色结点(每条路径上黑色结点的数量相等)
5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
插入的实现:
pCur为当前结点,parent为父亲结点,uncle为叔叔结点,grandpa为祖父结点
第一种情况:
pCur为红色,parent为红色,grandpa为黑色,uncle存在且为红色
做如下调整:parent改为黑色,grandpa改为红色,uncle改为黑色
这里写图片描述
第二种情况:
pCur为红色,parent为红色,grandpa为黑色,uncle不存在或存在且为黑色
做如下调整:grandpa的左孩子为parent,parent的左孩子为pCur时,对grandpa进行右单旋,parent改为黑色,grandpa改为红色;
grandpa的右孩子为parent,parent的右孩子为pCur时,对grandpa进行左单旋,parent改为黑色,grandpa改为红色;
这里写图片描述
第三种情况:
pCur为红色,parent为红色,grandpa为黑色,uncle不存在或存在且为黑色
做如下调整:grandpa的左孩子为parent,parent的右孩子为pCur时,先对parent进行左单旋并交换pCur和parent,然后对grandpa进行右单旋,pCurt改为黑色,grandpa改为红色;
grandpa的右孩子为parent,parent的左孩子为pCur时,先对parent进行右单旋并交换pCur和parent,然后对grandpa进行左单旋,pCurt改为黑色,grandpa改为红色;
这里写图片描述
完整代码如下:
rbt.cpp

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<stdio.h>#include<stdlib.h>using namespace std;enum Color{    RED,    BLACK};template<class K,class V>struct RBTreeNode{    RBTreeNode(const K& key,const V& value, Color color=RED)    : _value(value)    , _key(key)    , _left(NULL)    , _right(NULL)    , _parent(NULL)    , _color(color)    {}    K _key;    V _value;    RBTreeNode<K,V>* _left;    RBTreeNode<K, V>* _right;    RBTreeNode<K, V>* _parent;    Color _color;};template<class K, class V>class RBTree{    typedef RBTreeNode<K, V>Node;public:    RBTree()    :_pRoot(NULL)    {}    //插入    bool Insert(const K& key,const V& value)    {        if (NULL == _pRoot)        {            _pRoot = new Node(key, value);            return true;        }        //寻找插入位置        Node* pCur = _pRoot;        Node* parent = NULL;        while (pCur)        {            if (pCur->_key < key)            {                parent = pCur;                pCur = pCur->_right;            }            else if (pCur->_key>key)            {                parent = pCur;                pCur = pCur->_left;            }            else            {                return false;            }        }        //插入结点        pCur = new Node(key, value);        if (parent->_key > key)        {            parent->_left=pCur;            pCur->_parent = parent;        }        else        {            parent->_right=pCur;            pCur->_parent = parent;        }        while (parent != _pRoot && parent->_color == RED)        {            Node* grandpa = parent->_parent;            if ( grandpa->_left==parent)            {                Node* uncle = grandpa->_right;                {                    Node* uncle = grandpa->_right;                    //叔叔结点存在且为红色                    if (uncle &&uncle->_color == RED)                    {                        parent->_color = BLACK;                        uncle->_color = BLACK;                        grandpa->_color = RED;                        //继续向上调整                        pCur = grandpa;                        parent = pCur->_parent;                    }                    //叔叔结点不存在或叔叔结点存在为黑色                    else                    {                        //pCur为parent的右孩子                        if (pCur == parent->_right)                        {                            RotateL(parent);                            swap(pCur, parent);                        }                        parent->_color = BLACK;                        grandpa->_color = RED;                        RotateR(grandpa);                        break;                    }                }            }            //parent=grandpa->_right            else            {                Node* uncle = grandpa->_left;                //叔叔结点存在且为红色                if (uncle &&uncle->_color == RED)                {                    parent->_color = BLACK;                    uncle->_color = BLACK;                    grandpa->_color = RED;                    //继续向上调整                    pCur = grandpa;                    parent = pCur->_parent;                }                else                {                    //pCur为parent的左孩子                    if (pCur == parent->_left)                    {                        RotateR(parent);                        swap(pCur, parent);                    }                    parent->_color = BLACK;                    grandpa->_color = RED;                    RotateL(grandpa);                    break;                }            }            _pRoot->_color = BLACK;            return true;        }    }    //中序遍历    void Inorder()    {        return _Inorder(_pRoot);    }    //查找结点    bool Find(const K& key)    {         Node* pCur = _pRoot;        if (pCur == NULL)            return false;        else        {            while (pCur)            {                if (pCur->_key < key)                    pCur = pCur->_right;                else if (pCur->_key>key)                    pCur = pCur->_left;                else                    return true;            }        }        return true;    }    //判断是否平衡    bool IsBalance()    {        if (NULL == _pRoot)            return true;        if (_pRoot->_color == RED)            return false;        int k = 0;        Node* pCur = _pRoot;        while (pCur)        {            //记录其中一条路径黑色结点个数            if (pCur->_color == BLACK)                ++k;            pCur = pCur->_left;        }        //另一条路径黑色结点个数        int count = 0;        return _IsBalance(_pRoot, k, count);    }    //左旋    void RotateL(Node* parent)    {        Node* subR = parent->_right;        Node* subRL = subR->_left;        subR->_left = parent;        parent->_right = subRL;        if (subRL)            subRL->_parent = parent;        Node* pparent = parent->_parent;        if (NULL == pparent)        {            _pRoot = subR;            subR->_parent = NULL;        }        else        {            if (pparent->_left == parent)                pparent->_left = subR;            else                pparent->_right = subR;            subR->_parent = pparent;        }        parent->_parent = subR;    }    //右旋    void RotateR(Node* parent)    {        Node* subL = parent->_left;        Node* subLR = subL->_right;        subL->_right = parent;        parent->_left = subLR;        if (subLR)            subLR->_parent = parent;        Node* pparent = parent->_parent;        if (NULL == pparent)        {            _pRoot = subL;            subL->_parent = NULL;        }        else        {            if (pparent->_left == parent)                pparent->_left = subL;            else                pparent->_right = subL;            subL->_parent = pparent;        }        parent->_parent = subL;    }    void _Inorder(Node* pRoot)    {        if (NULL == pRoot)            return ;        _Inorder(pRoot->_left);        cout << pRoot->_key << "->";        _Inorder(pRoot->_right);    }    bool _IsBalance(Node* pRoot, int k, int count)    {        if (NULL == pRoot)            return true;        if (pRoot->_color == RED)        {            if (pRoot->_parent&&pRoot->_parent->_color == RED)                return false;        }        else            count++;        if (pRoot->_left == NULL&&pRoot->_right == NULL)        {             //比较两条路径黑色结点个数            if (k == count)                return true;            else                return false;        }        return _IsBalance(pRoot->_left, k, count) && _IsBalance(pRoot->_left, k, count);    }private:    Node* _pRoot;};void test(){    RBTree<int, int> rbt;    /*int array[] = {5,2,1,3,4,0,7,8,6};    int size = sizeof(array) / sizeof(array[0]);    for (int i = 0; i < size; i++)    {        rbt.Insert(array[i],i);    }*/    rbt.Insert(5, 5);    rbt.Insert(2, 2);    rbt.Insert(1, 1);    rbt.Insert(3, 3);    rbt.Insert(4, 4);    rbt.Insert(0, 0);    rbt.Insert(7, 7);    rbt.Insert(8, 8);    rbt.Insert(6, 6);    rbt.Inorder();    cout << "\n";    cout<<rbt.Find(5)<<endl;    cout << "\n";    cout << rbt.IsBalance() << endl;}int main(){    test();    system("pause");    return 0;}
0 0
原创粉丝点击