• 红黑树的创建


    红黑树的性质:

    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;
    }
  • 相关阅读:
    Linux下汇编语言学习笔记31 ---
    Linux下汇编语言学习笔记30 ---
    Linux下汇编语言学习笔记27 ---
    Linux下汇编语言学习笔记26 ---
    Linux下汇编语言学习笔记25 ---
    设计模式 关注点分离
    设计模式 关注点分离
    ALAsset和ALAssetRepresentation详解
    ALAsset和ALAssetRepresentation详解
    VIEW当中自定义属性的使用
  • 原文地址:https://www.cnblogs.com/Lune-Qiu/p/9045849.html
Copyright © 2020-2023  润新知