• 红黑树的创建


    红黑树的性质:

    1.红黑树中的节点是黑色或者红色;

    2.根节点一定是黑色

    3.终端节点是黑色

    4.没有2个红节点互为父子关系

    5.从任意节点出发到其所能到达的各个终端节点的各条路径上黑节点数目必须完全相同

    红黑树的创建:节点的初始颜色为红色,共7种情况

    1.空     变为黑色   结束

    2.父亲节点为黑     放入   结束

    3.父亲节点为红

        3.1叔叔节点为红

        父->黑   叔->黑   爷->红

        爷爷作为当前节点向上遍历

      3.2 叔叔节点为黑

        3.2.1父亲是爷爷 的左

           3.2.1.1当前节点Z是父亲的右

                父亲作为当前节点Z,

                以当前节点Z为支点左旋

           3.2.1.2 当前节点Z是父节点的左

               父->黑    爷->红

                以爷爷为支点右旋

                  结束

        3.2.2父亲是爷爷的右

            3.2.2.1当前节点Z是父亲的左

                父亲作为当前节点Z

                以Z为父的右旋

            3.2.2.2当前节点Z是父亲的右

                父->黑  爷->红

                以爷爷为支点左旋

    举个例子          

    代码:将根设为了全局变量,所有函数都可以直接改变他的值;左旋和右旋,在原来的基础上改动了一点点,变根的情况,更新rbt。

    typedef struct node1
    {
        int val;
        int color;
        struct node1* pLeft;
        struct node1* pRight;
        struct node1* pFather;
    } RBT;
    enum COLOR {RED,BLACK};
    RBT* rbt = NULL;
    void RightSpin(RBT** ppTree)
    {
        RBT* pTree = *ppTree;
        RBT* ptmp = pTree->pLeft;
        pTree->pLeft = ptmp->pRight;
        if(ptmp->pRight)
            ptmp->pRight->pFather = pTree;
        ptmp->pRight = pTree;
        ptmp->pFather = pTree->pFather;
        if(pTree->pFather)
        {
            if(pTree == pTree->pFather->pRight)
                pTree->pFather->pRight = ptmp;
            else
                pTree->pFather->pLeft = ptmp;
        }
        else
            rbt = ptmp;
        pTree->pFather = ptmp;
    }
    void LeftSpin(RBT** ppTree)
    {
        RBT* pTree = *ppTree;
        RBT* ptmp = pTree->pRight;
        pTree->pRight = ptmp->pLeft;
        if(ptmp->pLeft)
            ptmp->pLeft->pFather = pTree;
        ptmp->pLeft = pTree;
        ptmp->pFather = pTree->pFather;
        if(pTree->pFather)
        {
            if(pTree == pTree->pFather->pRight)
                pTree->pFather->pRight = ptmp;
            else
                pTree->pFather->pLeft = ptmp;
        }
        else
            rbt = ptmp;
        pTree->pFather = ptmp;
    }
    RBT* Find(RBT* pRBT,int num)
    {
        if(pRBT == NULL) return NULL;
        while(pRBT)
        {
            if(pRBT->val == num)
                return NULL;
            else if(pRBT->val > num)
            {
                if(pRBT->pLeft)
                    pRBT = pRBT->pLeft;
                else
                    return pRBT;
            }
            else
            {
                if(pRBT->pRight)
                    pRBT = pRBT->pRight;
                else
                    return pRBT;
            }
        }
    }
    RBT* GetUncle(RBT* ptmp)
    {
        if(ptmp->pFather == ptmp->pFather->pFather->pLeft)
            return ptmp->pFather->pFather->pRight;
        else
            return ptmp->pFather->pFather->pLeft;
    }
    void InsertNode(RBT* pRBT, int num)
    {
        RBT* ptmp = (RBT*)malloc(sizeof(RBT));
        ptmp->val = num;
        ptmp->color = RED;
        ptmp->pLeft = NULL;
        ptmp->pRight = NULL;
        ptmp->pFather = NULL;
        //查找
        RBT* pfather = Find(pRBT,num);
        //空树
        if(pRBT == NULL)
        {
            ptmp->color = BLACK;
            rbt = ptmp;
            return;
        }
        if(pfather->val > num)
            pfather->pLeft = ptmp;
        else
            pfather->pRight = ptmp;
        ptmp->pFather = pfather;
        //父节点为黑色
        if(pfather->color == BLACK)
        {
            return;
        }
        RBT* pGrandfather = NULL;
        RBT* pUncle = NULL;
        //父节点为红色
        while(pfather->color == RED)
        {
            pGrandfather = pfather->pFather;
            pUncle = GetUncle(ptmp);
            //叔叔为红色
            if(pUncle != NULL && pUncle->color == RED )
            {
                pfather->color = BLACK;
                pUncle->color = BLACK;
                pGrandfather->color = RED;
                ptmp = pGrandfather;
                pfather = ptmp->pFather;
    
                if(pfather == NULL)
                {
                    ptmp->color = BLACK;
                    return;
                }
                continue;
            }
            //没有叔叔或叔叔是黑色
            if(pUncle == NULL || pUncle->color == BLACK)
            {
                //父为爷左
                if(pfather == pGrandfather->pLeft)
                {
                    //当前节点为父右
                    if(ptmp == pfather->pRight)
                    {
                        ptmp = pfather;
                        LeftSpin(&ptmp);
                        pfather = ptmp->pFather;
                        continue;
                    }
                    //当前节点为父左
                    if(ptmp == pfather->pLeft)
                    {
                        pfather->color = BLACK;
                        pGrandfather->color = RED;
                        RightSpin(&pGrandfather);
                        break;
                    }
                }
                if(pfather == pGrandfather->pRight)
                {
                    if(ptmp == pfather->pLeft)
                    {
                        ptmp = pfather;
                        RightSpin(&ptmp);
                        pfather = ptmp->pFather;
                        continue;
                    }
                    if(ptmp == pfather->pRight)
                    {
                        pfather->color = BLACK;
                        pGrandfather->color = RED;
                        LeftSpin(&pGrandfather);
                        break;
                    }
                }
            }
        }
        rbt->color =BLACK;
    }
  • 相关阅读:
    编译类与解释类语言区别
    计算机核心/系统/python运行
    Python_报错:TypeError: write() argument must be str, not int
    Python_报错:ValueError: binary mode doesn't take an encoding argument
    Python_报错:EOFError: Ran out of input
    Linux安装Redis报错`cc:命令未找到`
    Linux(CentOS-8)安装MySQL8.0.11
    linux安装MySQL报 error while loading shared libraries: libtinfo.so.5 解决办法
    SSM整合大体步骤
    JSON数据显示在jsp页面上中文乱码的解决办法
  • 原文地址:https://www.cnblogs.com/Lune-Qiu/p/9045849.html
Copyright © 2020-2023  润新知