红黑树的简单实现-RBTree

来源:互联网 发布:tk域名续费 编辑:程序博客网 时间:2024/06/11 23:15

红黑树是一个被广泛运用的平衡二叉树,同时满足以下规则
1.每个节点不是红色就是黑色
2.根节点为黑
3.不存在连续红节点
4.每条路径上黑色节点数相等,(空节点视为黑色)
这样一来,红黑树可以保持最长路径不超过最短路径的两倍,保持近似平衡,搜索时间复杂度是O(lgN)

下面是红黑树调节节点平衡与颜色的简介,当插入节点后出现连续红节点后,判断叔叔是否存在和叔叔的颜色,
若是叔叔存在且颜色为红时
这里写图片描述
叔叔不存在 或者 叔叔存在且颜色为黑时,如下图调整,四种情况四种旋转
这里写图片描述
下面是实现代码:

#include <iostream>using namespace std;enum Color{    RED,    BLACK};template <class T>struct RBTreeNode{    RBTreeNode<T>* _left;    RBTreeNode<T>* _right;    RBTreeNode<T>* _parent;    Color _color;    T _key;    RBTreeNode(T key)        :_left(NULL),        _right(NULL),        _parent(NULL),        _color(RED),        _key(key)    {}};template <class T>class RBTree{    typedef RBTreeNode<T> Node;public:    RBTree()        :_root(NULL)    {}    void RotateR(Node* parent)    {        Node* subL = parent->_left;        Node* PParent = parent->_parent;        Node* subLR = subL->_right;        parent->_left = subLR;        subL->_right = parent;        parent->_parent = subL;        if (subLR)        {            subLR->_parent = parent;        }        if (PParent==NULL)        {            _root = subL;            subL->_parent = NULL;        }        else if (PParent->_key > parent->_key)        {            subL->_parent = PParent;            PParent->_left = subL;        }        else if (PParent->_key < parent->_key)        {            subL->_parent = PParent;            PParent->_right = subL;        }    }    void RotateL(Node* parent)    {        Node* PParent = parent->_parent;        Node* subR = parent->_right;        Node* subRL = subR->_left;        parent->_right = subRL;        subR->_left = parent;        parent->_parent = subR;        if (subRL)        {            subRL->_parent = parent;        }        if (PParent == NULL)        {            _root = subR;            subR->_parent = NULL;        }        else if (PParent->_key > parent->_key)        {            subR->_parent = PParent;            PParent->_left = subR;        }        else if (PParent->_key < parent->_key)        {            subR->_parent = PParent;            PParent->_right = subR;        }    }    bool Insert(const T& key)    {        if (_root == NULL)//空树直接插入        {            _root = new Node(key);            _root->_color = BLACK;            return true;        }        Node* cur = _root;//非空 从根节点开始 向下找位置        Node* parent = NULL;        while (cur)        {            if (key == cur->_key)            {                return false;            }            else if (key < cur->_key)            {                parent = cur;                cur = cur->_left;            }            else if (key>cur->_key)            {                parent = cur;                cur = cur->_right;            }        }        cur = new Node(key);        cur->_parent = parent;        if (parent->_key > key)        {            parent->_left = cur;        }        else if (parent->_key < key)        {            parent->_right = cur;        }        //调节节点颜色        while (parent&&parent->_color == RED)        {            Node* PParent = parent->_parent;            if (PParent->_left == parent)//父亲是祖父的左            {                Node* uncle = PParent->_right;                if (uncle&&uncle->_color == RED)//叔叔为红                {                    parent->_color = uncle->_color = BLACK;                    PParent->_color = RED;                    cur = PParent;                    parent = cur->_parent;                }                else//叔叔不存在  或者叔叔为黑                {                    if (cur == parent->_left)                    {                        //右单旋                        RotateR(PParent);                        PParent->_color = RED;//祖父变红                        parent->_color = BLACK;//父亲变黑                    }                    else//左右双旋                    {                        RotateL(parent);                        RotateR(PParent);                        PParent->_color = RED;//祖父 变红                        cur->_color = BLACK;//当前节点变黑                    }                }            }            else if (PParent->_right == parent)//父亲是祖父的右            {                Node* uncle = PParent->_left;                if (uncle&&uncle->_color == RED)//叔叔为红                {                    parent->_color = uncle->_color = BLACK;                    PParent->_color = RED;                    cur = PParent;                    parent = cur->_parent;                }                else//叔叔不存在  或者叔叔为黑                {                    if (cur == parent->_right)//cur为父亲的右 左单旋                    {                        RotateL(PParent);//左单旋                        parent->_color = BLACK;//父亲变红                        PParent->_color = RED;//祖父变黑                    }                    else                    {                        //右左双旋                        RotateR(parent);                        RotateL(PParent);                        cur->_color = BLACK;                        PParent->_color = RED;                    }                }            }_root->_color = BLACK;        }return true;    }    void Printf()    {        _printf(_root);    }    void _printf(Node*& root)    {        if (root == NULL)            return;        _printf(root->_left);        printf("%d  ",root->_key);        _printf(root->_right);    }protected:    Node* _root;};int main(){    int a[] = {3,2,4,5,7,9,8,0,12,13,15};    /*int a[] = { 10,5,3 };*/    /*int a[] = { 10,5,8 };*/    /*int a[] = { 3,5,10 };*/    /*int a[] = { 3,10,5};*/    RBTree<int> t;    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)        t.Insert(a[i]);    t.Printf();    system("pause");    return 0;}

结果如下
这里写图片描述
如有不足 ,请不吝赐教