【数据结构】红黑树

一、红黑树
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示结点的颜色,可以是 red 或者 black ,通过对任何一条从根节点到叶子节点简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似平衡,而且在实际应用中发现红黑树性能确实比 AVL 树 性能高。
AVL树实现代码: https://blog.csdn.net/lz201788/article/details/79451815

二、性质
1.每个节点不是红色就是黑色
2.树的根节点是黑色的
3.如果一个节点是红色的,则它的两个孩子节点是黑色的(没有两个连续的红色节点)
4.对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点(每条路径上黑色节点的数量相等)

三、插入实现

【情况一】
若树为空,插入后违反性质2,需要将新增节点改成黑色。

【情况二】
插入节点的父亲节点为黑色,不违反任何性质,直接插入。

约定:cur为当前节点,p为父亲节点,g为祖父节点,u为叔叔节点
【情况三】
这里写图片描述

【情况四】
这里写图片描述

【情况五】
这里写图片描述
【代码实现】
【RBTree.h】

#pragma once
#include<iostream>
using namespace std;

enum Color
{
    RED,
    BLACK
};
template<class K,class V>
struct RBNode
{
    RBNode()
    :_Lchild(NULL)
    ,_Rchild(NULL)
    ,_Parent(NULL)
    , _color(RED)
    { }
    RBNode(K key,V value,Color color=RED)
        :_Lchild(NULL)
        , _Rchild(NULL)
        , _Parent(NULL)
        , _key(key)
        , _value(value)
        , _color(color)
    { }
    RBNode<K, V>* _Lchild;
    RBNode<K, V>* _Rchild;
    RBNode<K, V>* _Parent;
    K _key;
    V _value;
    Color _color;
};

template<class K, class V>
class RBTree
{
    typedef RBNode<K, V> Node;
    typedef RBNode<K, V>* pNode;
public:
    RBTree()
    {
        Root = NULL;
    }
    bool Insert(K k,V v)
    {
        return _Insert(Root,k,v);
    }
    void InOrder()
    {
        _InOrder(Root);
    }
    bool CheckRBT()
    {
        int blackcount = 0;
        int k = 0;
        pNode cur = Root;
        while (cur)
        {
            if (cur->_color == BLACK)
                blackcount++;
            cur = cur->_Lchild;
        }
        return _CheckRBT(Root,blackcount,k);
    }
private:
    bool _CheckRBT(pNode pRoot,int blackcount,int k)
    {
        if (pRoot == NULL)
        {
            if (blackcount == k)
                return true;
            else
                return false;
        }
        if (pRoot->_color == RED&&pRoot->_Parent->_color == RED)
            return false;
        if (pRoot->_color == BLACK)
            k++;
        return _CheckRBT(pRoot->_Lchild,blackcount,k);
        return _CheckRBT(pRoot->_Rchild, blackcount, k);

    }
    void _InOrder(pNode pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_Lchild);
            cout << "<" << pRoot->_key << "," << pRoot->_value << ">" << endl;
            _InOrder(pRoot->_Rchild);
        }
    }
    bool _Insert(pNode& pRoot,K k,V v)
    {
        pNode newNode = new Node(k, v);
        if (pRoot == NULL)          //情况一
        {
            pRoot = newNode;
            newNode->_color = BLACK;
        }
        pNode cur = pRoot;
        pNode pParent = NULL;
        while (cur)                 
        {                           //查找要插入的位置
            pParent = cur;
            if (cur->_key > k)
                cur = cur->_Lchild;
            else if (cur->_key < k)
                cur = cur->_Rchild;
            else
                return false;     //k已存在
        }
        if (pParent->_key>k)
        {
            pParent->_Lchild = newNode;
            newNode->_Parent = pParent;
        }
        else
        {
            pParent->_Rchild = newNode;
            newNode->_Parent = pParent;
        }
        cur = newNode;

        pNode u = NULL;
        pNode p = pParent;
        while (cur!=Root&&p->_color==RED)
        {
            pNode g = p->_Parent;
            if (p== g->_Lchild)
                u = g->_Rchild;
            else
                u = g->_Lchild;

            if (p->_color == BLACK)        //情况二
                return true;
            else if (cur->_color==RED&&u->_color==RED)   //情况三
            {
                p->_color = BLACK;
                u->_color = BLACK;
                if (g!=Root)
                g->_color = RED;

                cur = g;
                p = cur->_Parent;
            }
            else if (cur->_color == RED&&g->_color == BLACK&&(u->_color==BLACK||u==NULL))   //情况四
            {
                p->_color = BLACK;
                g->_color = RED;
                if (cur == p->_Lchild&&p == g->_Lchild)
                {
                    //右单旋
                    RotateRight(g);
                }
                else if (cur == p->_Rchild&&p == g->_Rchild)
                {
                    //左单旋
                    RotateLeft(g);
                }
            }
            else if (cur->_color == RED&&g->_color == BLACK && (u->_color == BLACK || u == NULL))
            {
                if (p == g->_Lchild&&cur == p->_Rchild)
                {
                    //左单旋
                    RotateLeft(p);
                    swap(cur, p);
                }
                else if (p == g->_Rchild&&cur == p->_Lchild)
                {
                    //右单旋
                    RotateRight(p);
                    swap(cur, p);
                }
            }
            if (g == Root)
                g->_color = BLACK;
        }
        return true;
    }
    void RotateLeft(pNode g)
    {
        pNode pSubR = g->_Rchild;
        pNode pSubRL = pSubR->_Lchild;
        pNode pParent = g->_Parent;

        g->_Rchild = pSubRL;
        if (pSubRL != NULL)
            pSubRL->_Parent = g;
        pSubR->_Lchild = g;
        g->_Parent = pSubR;
        if (pParent == NULL)
            Root = pSubR;
        else if (pParent != NULL&&g == pParent->_Lchild)
        {
            pParent->_Lchild = g;
            g->_Parent = pParent;
        }
        else if (pParent != NULL&&g == pParent->_Rchild)
        {
            pParent->_Rchild = g;
            g->_Parent = pParent;
        }
    }
    void RotateRight(pNode g)
    {
        pNode pSubL = g->_Lchild;
        pNode pSubLR = pSubL->_Rchild;
        pNode pParent = g->_Parent;

        g->_Lchild = pSubLR;
        if (pSubLR)
            pSubLR->_Parent = g;
        pSubL->_Rchild = g;
        g->_Parent = pSubL;
        if (pParent == NULL)
            Root = pSubL;
        else if (pParent != NULL&&g == pParent->_Lchild)
        {
            pParent->_Lchild = pSubL;
            pSubL->_Parent = pParent;
        }
        else if (pParent != NULL&&g == pParent->_Rchild)
        {
            pParent->_Rchild = pSubL;
            pSubL->_Parent = pParent;
        }

    }

private:
    pNode Root;
};
//【测试函数】
void Test()
{
    RBTree<int, int> t;
    int arr[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
    int size = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < size; i++)
    {
        t.Insert(arr[i], i);
    }
    t.InOrder();
    if (t.CheckRBT() == true)
        cout << "是红黑树" << endl;
    else
        cout << "不是红黑树" << endl;
}

【test.cpp】

#include"RBTree.h"

int main()
{
    Test();
    system("pause");
    return 0;
}

【删除】:(参考下面的博客)
http://www.cnblogs.com/fornever/archive/2011/12/02/2270692.html
https://blog.csdn.net/chenhuajie123/article/details/11951777

发布了70 篇原创文章 · 获赞 92 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章