红黑树插入、删除、查找算法学习

红黑树(red-black tree)是许多“平衡”搜索树中的一种,可以保证在最坏情况下基本动态集合操作的时间复杂度为O(lgn)。

一、红黑树的性质

红黑树是一棵二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出2倍,因而是接近平衡的。树中每个结点内含五个域,color,key,lchild,rchild,parent。如果相应的指针域没有,则设为NIL。
一棵红黑是满足以下性质的二叉搜索树:
1. 每个结点要么是红色的,要么是黑色的。
2. 根结点是黑色的。
3. 每个叶结点(NIL)是黑色的。
4. 如果一个结点是红色色的,那么它的两个子结点都是黑色的。
5. 对每个结点,从该结点到其子结点的简单路径上,均包含相同数目的黑色结点。

为了便于处理红黑树代码中的边界条件,使用一个哨兵来代表NIL。哨兵T.Nil是一个与书中普通结点有相同属性的对象,他的color属性是BLACK,其他属性可以设为任意值。
0

红黑树结构描述如下:

typedef int KeyType;        //假定关键字类型为整数
typedef enum {RED = 1,BLACK = 0}  Color;  //定义颜色类型
typedef struct node         //结点类型
{
    KeyType key;       //关键字项
    Color color;          //颜色
    struct node *lchild, *rchild, *parent; //左右孩子和双亲
} *pRBTNode, RBTNode;

typedef struct Tree    //红黑树类型
{
    pRBTNode Root;     //根结点
    pRBTNode Nil;      //哨兵

}*RBTree,RBTreeNode;

二、旋转

当在对红黑树进行插入和删除等操作时,对树做了修改,可能会违背红黑树的性质。为了保持红黑树的性质,可以通过对树进行旋转,即修改树中某些结点的颜色及指针结构,以保持它特有的性质。
有两种旋转方式:左旋和右旋,如下图:

当在某个结点x上做左旋操作时,假设它的右孩子y不是T->Nil,x可以为树内任意右孩子而不是T->Nil的结点。左旋以x到y之间的链为“支轴”进行,它使y成为该子树新的根结点,x成为y的左孩子,y的左孩子b成为x的右孩子。
C语言算法实现如下:

void LeftRotate(RBTree T, pRBTNode x) //左旋转
{
    pRBTNode y;
    y = x->rchild;
    x->rchild = y->lchild;
    if (y->lchild != T->Nil)
        y->lchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->lchild = x;
    if (x != T->Nil)
        x->parent = y;
}

右旋与左旋操作代码对称,在旋转操作中只有指针改变,其他所有属性都保持不变。

三、插入

向一棵含有n个结点的红黑树中插入一个新结点的操作可以在O(lgn)时间内完成。

void RBTreeInsert(RBTree T, KeyType key)   //插入算法
{
    pRBTNode x,y,z;
    x = T->Root;
    y = T->Nil;
    z = (pRBTNode)malloc(sizeof(RBTNode));
    z->color = RED;
    z->key = key;
    z->parent = NULL;
    z->lchild = NULL;
    z->rchild = NULL;
    while (x != T->Nil)
    {
        y = x;
        if (z->key<x->key)
            x = x->lchild;
        else x = x->rchild;
    }
    z->parent = y;
    if (y != T->Nil)
    {
        if (z->key>y->key)
            y->rchild = z;
        else if (z->key<y->key)
            y->lchild = z;
    }
    else
    {
        T->Root = z;
    }
    z->lchild = T->Nil;
    z->rchild = T->Nil;

    RBTreeInsertFixup(T, z);
}

每次插入一个结点,都将其着为红色,但可能违反红黑性质,为此,调用RBTreeInsertFixup来保持红黑性质

void RBTreeInsertFixup(RBTree T, pRBTNode z)   //重新着色并旋转结点
{
    pRBTNode y;
    while ((z->parent != NULL) && (z->parent->color == RED))
    {
        if (z->parent == z->parent->parent->lchild)
        {
            y = z->parent->parent->rchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;          //情况1
                y->color = BLACK;                  //情况1
                z->parent->parent->color = RED;    //情况1
                z = z->parent->parent;             //情况1
            }
            else
            {
                if (z == z->parent->rchild)
                {
                    z = z->parent;                //情况2
                    LeftRotate(T,z);              //情况2
                }
                z->parent->color = BLACK;         //情况3
                z->parent->parent->color = RED;   //情况3
                RightRotate(T, z->parent->parent);//情况3
            }
        }
        else
        {
            y = z->parent->parent->lchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if (z == z->parent->lchild)
                {
                    z = z->parent;
                    RightRotate(T, z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                LeftRotate(T, z->parent->parent);
            }
        }
    }
    T->Root->color = BLACK;
    T->Nil->color = BLACK;</span><span style="font-size:24px;">
}

在对红黑树进行插入操作时,我们一般总是插入红色的结点,因为这样可以在插入过程中尽量避免对树的调整。如果插入的结点是根结点,性质2会被破坏,如果插入结点的父结点是红色,则会破坏性质4,其他性质不会被破坏。
如果插入节点的父亲为黑色,则不需要进行调整,若为红色,有三种情况需要讨论。

情况1:z的叔结点y是红色的


插入后的结点是z,由于z和它的父结点z.parent都是红色的,违反了性质4,。由于z的叔结点y是红色的,可以应用程序中的情况1。同时改变父、叔节点颜色为黑色,并将爷爷节点置红,指针z沿树上升,这样在这个局部范围内,保持黑色平衡。如果z此时为根,则置z为黑色,调整结束,否则相当于又插入了一个红色节点,进行新一轮迭代,得到情况2。

情况2:z的叔结点y是黑色的且z是一个右孩子。


再一次z及其父结点都为红色,但z的叔结点是黑色的,因为z是z.parent的右孩子,可以应用情况2。在执行一次左旋后,得到结果如情况3所示。

情况3:z的叔结点y是黑色的且z是一个左孩子。


现在,z是其父结点的左孩子,可以应用情况3,重新着色并执行一次右旋得到一棵合法的红黑树。
合法红黑树:

四、删除

删除一个结点要花费O(lgn)时间,与插入相比,删除操作要复杂些。

第一:先看最简单情况,即删除红色节点。删除红色节点,不影响红黑树平衡性质,只需要删除红色节点,不需要进行调整,因为不影响红黑树的性质。 黑色节点没有增多也没有减少。如图:

注意:以下几种单支情况破坏了红黑树的平衡状态。在平衡的红黑树中不可能出现。所以,平衡状态下红黑树要么是单支黑-红,要么有两个子节点。

第二:删除单支黑节点

第三:若删除节点有左右两个儿子,即左右子树。需要按照二叉搜索树的删除规律,从右子树中找最小的替换删除节点(该节点至多有一个右子树,无左子树),将该节点记为y, 删除节点记为z,y的右子树记为x(可能为空)。

删除规则:用y替换z,交换y与z颜色,同时y = z,改变y的指向,让y指向最终删除节点。为了便于理解,可以先这样假设:将y与z的数据交换,但颜色不交换,这样,实际相当于将删除转移到了y节点,而z处保持原先状态(处于平衡)。此时可以完全不用了理会z节点,直接删除y节点即可。因为y最多只有一个右子树,无左子树,这便转移到了“第二”。

对于删除y节点,有几种考虑:
1. 若y为红色,则这种情况如上述”第一“所述,并不影响平衡性。
2. 若y为黑色,则删除y后,x替换了y的位置,这样x子树相对于兄弟节点w为根的子树少了一个黑节点,影响平衡,需要进行调整。
剩下的调整工作就是将x子树中找一合适红色节点,将其置黑,使得x子树与w子树达到平衡。若x为红色,直接将x置为黑色,即可达到平衡。

若x为黑色,则分下列几种情况:
情况1: x的兄弟w为红色,则w的子树必然全黑,w父亲p也为黑。改变p与w的颜色,同时对p做一次左旋,这样就将情况1转变为情况2,3,4的一种。

情况2: x的兄弟w为黑色,x与w的父亲颜色可红可黑。因为x子树相对于其兄弟w子树少一个黑色节点,可以将w置为红色,这样,x子树与w子树黑色节点一致,保持了平衡。new x为x与w的父亲。new x相对于它的兄弟节点new w少一个黑色节点。如果new x为红色,则将new x置为黑,则整棵树平衡。

情况3: w为黑色,w左孩子红色,右孩子黑色。 交换w与左孩子的颜色,对w进行右旋。转换为情况4。
这里写图片描述
情况4: w为黑色,右孩子为红色。交换w与父亲p颜色,同时对p做左旋。这样左边缺失的黑色就补回来了,同时,将w的右孩子置黑,这样左右都达到平衡。

情况2是最好理解的,减少右子树的一个黑色节点,使x与w平衡,将不平衡点上移至x与w的父亲,进行下一轮迭代。情况1:如果w为红色,通过旋转,转成成情况1,2,3进行处理。而情况3转换为情况4进行处理。也就是说,情况4是最接近最终解的情况。情况4:右儿子是红色节点,那么将缺失的黑色交给右儿子,通过旋转,达到平衡。

void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v)   //v替换u
{
    if (u->parent == T->Nil)
        T->Root = v;
    else if (u == u->parent->lchild)
        u->parent->lchild = v;
    else u->parent->rchild = v;
    v->parent = u->parent;
}
void RBTreeDelete(RBTree T, pRBTNode z)    //删除
{
    pRBTNode x, y;
    Color y_original_color;
    y = z;
    y_original_color = y->color;
    if (z->lchild == T->Nil)
    {
        x = z->rchild;
        RBTreeTransplant(T, z, z->rchild);
    }
    else if (z->rchild == T->Nil)
    {
        x = z->lchild;
        RBTreeTransplant(T, z, z->lchild);
    }
    else
    {
        y = TreeMin(T, z->rchild);
        y_original_color = y->color;
        x = y->rchild;
        if (y->parent == z)
            x->parent = y;
        else
        {
            RBTreeTransplant(T, y, y->rchild);
            y->rchild = z->rchild;
            y->rchild->parent = y;
        }
        RBTreeTransplant(T, z, y);
        y->lchild = z->lchild;
        y->lchild->parent = y;
        y->color = z->color;
    }
    if (y_original_color = BLACK)
        RBTreeDeleteFixup(T, x);
    free(y);
}
void RBTreeDeleteFixup(RBTree T, pRBTNode x)  //辅助删除过程
{
    pRBTNode w;
    while ((x != T->Root) && (x->color == BLACK))
    {
        if (x == x->parent->lchild)
        {
            w = x->parent->rchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                LeftRotate(T, x->parent);
                w = x->parent->rchild;
            }
            if (w->lchild->color == BLACK && w->rchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->rchild->color == BLACK)
                {
                    w->lchild->color = BLACK;
                    w->color = RED;
                    RightRotate(T, w);
                    w = x->parent->rchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->rchild->color = BLACK;
                LeftRotate(T, x->parent);
                x = T->Root;
            }
        }
        else
        {
            w = x->parent->lchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                RightRotate(T, x->parent);
                w = x->parent->lchild;
            }
            if (w->rchild->color == BLACK&&w->lchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->lchild->color == BLACK)
                {
                    w->rchild->color = BLACK;
                    w->color = RED;
                    LeftRotate(T, w);
                    w = x->parent->lchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->lchild->color = BLACK;
                RightRotate(T, x->parent);
                x = T->Root;
            }
        }
    }
    x->color = BLACK;
}

五、完整的C语言程序

写一个完整的C程序,测试插入,删除等算法。运行程序,根据提示进行相应的操作。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAXSIZE 1000

typedef int KeyType;        //假定关键字类型为整数
typedef enum {RED = 1,BLACK = 0}  Color;  //定义颜色类型
typedef struct node         //结点类型
{
    KeyType key;       //关键字项
    Color color;          //颜色
    struct node *lchild, *rchild, *parent; //左右孩子和双亲
} *pRBTNode, RBTNode;

typedef struct Tree    //红黑树类型
{
    pRBTNode Root;     //根结点
    pRBTNode Nil;      //哨兵

}*RBTree,RBTreeNode;
/*-------------------------------------------------------*/
RBTree InitRBTree();   //初始化
void LeftRotate(RBTree T, pRBTNode x);     //左旋转
void RightRotate(RBTree T, pRBTNode x);     //右旋转
void RBTreeInsertFixup(RBTree T, pRBTNode z);   //重新着色并旋转结点
void RBTreeInsert(RBTree T, KeyType key);   //插入算法
void InorderTreeWalk_Recursive(pRBTNode t);     //中序遍历的递归算法
void InorderTreeWalk_NonRecursive(RBTree T);     //中序遍历的非递归算法
void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v);  //v替换u
pRBTNode TreeMin(RBTree T, pRBTNode t);     //查找关键字最小的结点
pRBTNode TreeMax(RBTree T, pRBTNode t);     //查找关键字最大的结点
void RBTreeDeleteFixup(RBTree T, pRBTNode x);  //辅助删除过程
void RBTreeDelete(RBTree T, pRBTNode z);    //删除
pRBTNode SearchNodeByKey(RBTree T, KeyType key);  //根据关键字查找结点
RBTree CreateRandom();   //随机生成一棵红黑树
void menu();     //菜单
/*-------------------------------------------------------*/

int main()
{
    RBTree Tree = NULL;
    KeyType key;
    pRBTNode x;
    char ch;
    menu();
    while (1)
    {
        printf(">");
        ch = getchar();
        switch (ch)
        {
        case '0':
        {
            menu();
            break;
        }
        case '1':
        {
            Tree = InitRBTree();
            break;
        }
        case '2':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            printf("Enter key:");
            scanf("%d", &key);
            RBTreeInsert(Tree, key);
            printf("Insert Success!\n");
            break;
        }
        case '3':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            printf("Enter the key you want to delete:");
            scanf("%d", &key);
            x = SearchNodeByKey(Tree, key);
            if (x != Tree->Nil)
            {
                RBTreeDelete(Tree, x);
                printf("Delete Success!\n");
            }
            else 
                printf("No this key.Delete failed! \n");
            break;
        }
        case '4':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            x = TreeMin(Tree, Tree->Root);
            printf("the min key:%d\n",x->key);
            break;
        }
        case '5':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }
            x = TreeMax(Tree, Tree->Root);
            printf("the max key:%d\n", x->key);
            break;
        }
        case '6':
        {
            if (Tree == NULL)
            {
                printf("The tree is null.Please Create it first!\n");
                break;
            }

            InorderTreeWalk_Recursive(Tree->Root);
            printf("\n");
            break;
        }
        case '8':
        {
            Tree = CreateRandom();
            break;
        }
        case 'e':
            return;
        case '\n':
            break;
        default:
            menu();
            break;
        }
    }
    return 0;
}

/*-------------------------------------------------------*/
void menu()     //菜单
{
    printf("*--------------Red-Black Tree-----------------*\n");
    printf("1----Create RBTree.        4----Minimum Node.\n");
    printf("2----Insert Node.          5----Maximum Node.\n");
    printf("3----Delete Node.          6----Print RBTree.\n");
    printf("8----Create RBtree Random(100000 Nodes)\n");
    printf("0----Help.                 e----Exit\n");
    printf("*---------------------------------------------*\n");
}
/*-------------------------------------------------------*/
RBTree InitRBTree()   //初始化
{
    RBTree T = (RBTree)malloc(sizeof(RBTreeNode));
    T->Nil = (pRBTNode)malloc(sizeof(RBTNode));
    T->Root = (pRBTNode)malloc(sizeof(RBTNode));
    T->Nil->color = BLACK;
    T->Nil->lchild = NULL;
    T->Nil->rchild = NULL;
    T->Nil->parent = NULL;
    T->Nil->key = -1;
    T->Root = T->Nil;
    printf("Enter the number of integers(EndFlag:0):\n");
    KeyType key, EndFlag = 0;
    scanf("%d", &key);
    while (key != EndFlag)
    {
        RBTreeInsert(T, key);
        scanf("%d", &key);
    }
    return T;
}
/*-------------------------------------------------------*/
RBTree CreateRandom()   //随机生成一棵红黑树
{
    RBTree T = (RBTree)malloc(sizeof(RBTreeNode));
    T->Nil = (pRBTNode)malloc(sizeof(RBTNode));
    T->Root = (pRBTNode)malloc(sizeof(RBTNode));
    T->Nil->color = BLACK;
    T->Nil->lchild = NULL;
    T->Nil->rchild = NULL;
    T->Nil->parent = NULL;
    T->Nil->key = -1;
    T->Root = T->Nil;
    KeyType key;
    int i = 0;
    srand(time(NULL));
    while (i++ <100000)
    {
        key = rand()%100000 + 1; //生成一个1-32768之间的数字
        RBTreeInsert(T, key);
    }
    return T;
}
/*-------------------------------------------------------*/
void LeftRotate(RBTree T, pRBTNode x) //左旋转
{
    pRBTNode y;
    y = x->rchild;
    x->rchild = y->lchild;
    if (y->lchild != T->Nil)
        y->lchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->lchild = x;
    if (x != T->Nil)
        x->parent = y;
}
/*-------------------------------------------------------*/
void RightRotate(RBTree T, pRBTNode x)     //右旋转
{
    pRBTNode  y;
    y = x->lchild;
    x->lchild = y->rchild;
    if (y->rchild != T->Nil)
        y->rchild->parent = x;
    if (x != T->Nil)
        y->parent = x->parent;
    if (x->parent == T->Nil)
        T->Root = y;
    else
    {
        if (x->parent->lchild == x)
            x->parent->lchild = y;
        else
            x->parent->rchild = y;
    }
    y->rchild = x;
    if (x != T->Nil)
        x->parent = y;
}
/*-------------------------------------------------------*/
void RBTreeInsertFixup(RBTree T, pRBTNode z)   //重新着色并旋转结点
{
    pRBTNode y;
    while ((z->parent != NULL) && (z->parent->color == RED))
    {
        if (z->parent == z->parent->parent->lchild)
        {
            y = z->parent->parent->rchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;          //情况1
                y->color = BLACK;                  //情况1
                z->parent->parent->color = RED;    //情况1
                z = z->parent->parent;             //情况1
            }
            else
            {
                if (z == z->parent->rchild)
                {
                    z = z->parent;                //情况2
                    LeftRotate(T,z);              //情况2
                }
                z->parent->color = BLACK;         //情况3
                z->parent->parent->color = RED;   //情况3
                RightRotate(T, z->parent->parent);//情况3
            }
        }
        else
        {
            y = z->parent->parent->lchild;
            if ((y != NULL) && (y->color == RED))
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if (z == z->parent->lchild)
                {
                    z = z->parent;
                    RightRotate(T, z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                LeftRotate(T, z->parent->parent);
            }
        }
    }
    T->Root->color = BLACK;
    T->Nil->color = BLACK;
}
/*-------------------------------------------------------*/
void RBTreeInsert(RBTree T, KeyType key)   //插入算法
{
    pRBTNode x,y,z;
    x = T->Root;
    y = T->Nil;
    z = (pRBTNode)malloc(sizeof(RBTNode));
    z->color = RED;
    z->key = key;
    z->parent = NULL;
    z->lchild = NULL;
    z->rchild = NULL;
    while (x != T->Nil)
    {
        y = x;
        if (z->key<x->key)
            x = x->lchild;
        else x = x->rchild;
    }
    z->parent = y;
    if (y != T->Nil)
    {
        if (z->key>y->key)
            y->rchild = z;
        else if (z->key<y->key)
            y->lchild = z;
    }
    else
    {
        T->Root = z;
    }
    z->lchild = T->Nil;
    z->rchild = T->Nil;

    RBTreeInsertFixup(T, z);
}
/*-------------------------------------------------------*/
void InorderTreeWalk_Recursive(pRBTNode t)     //中序遍历的递归算法
{
    if (t->key != -1)
    {
        InorderTreeWalk_Recursive(t->lchild);   //访问左子树
        printf("%d ", t->key);        //访问结点
        InorderTreeWalk_Recursive(t->rchild);   //访问右子树
    }
}
/*-------------------------------------------------------*/
void InorderTreeWalk_NonRecursive(RBTree T)     //中序遍历的非递归算法
{
    int top = -1;
    pRBTNode Stack[MAXSIZE];
    pRBTNode x = T->Root;
    while (top != -1 || x != T->Nil)
    {
        while (x != T->Nil)
        {
            if (top == MAXSIZE - 1)
            {
                printf("overflow!!\n");
                return;
            }
            else
            {
                Stack[++top] = x;
                x = x->lchild;
            }
        }
        x = Stack[top--];
        printf("%d ", x->key);
        x = x->rchild;
    }
}
/*-------------------------------------------------------*/
void RBTreeTransplant(RBTree T, pRBTNode u, pRBTNode v)   //v替换u
{
    if (u->parent == T->Nil)
        T->Root = v;
    else if (u == u->parent->lchild)
        u->parent->lchild = v;
    else u->parent->rchild = v;
    v->parent = u->parent;
}
/*-------------------------------------------------------*/
pRBTNode TreeMin(RBTree T, pRBTNode t)     //查找关键字最小的结点
{
    pRBTNode x = t;
    while (x->lchild != T->Nil)
        x = x->lchild;
    return x;
}
/*-------------------------------------------------------*/
pRBTNode TreeMax(RBTree T, pRBTNode t)     //查找关键字最大的结点
{
    pRBTNode x = t;
    while (x->rchild != T->Nil)
        x = x->rchild;
    return x;
}
/*-------------------------------------------------------*/
void RBTreeDelete(RBTree T, pRBTNode z)    //删除
{
    pRBTNode x, y;
    Color y_original_color;
    y = z;
    y_original_color = y->color;
    if (z->lchild == T->Nil)
    {
        x = z->rchild;
        RBTreeTransplant(T, z, z->rchild);
    }
    else if (z->rchild == T->Nil)
    {
        x = z->lchild;
        RBTreeTransplant(T, z, z->lchild);
    }
    else
    {
        y = TreeMin(T, z->rchild);
        y_original_color = y->color;
        x = y->rchild;
        if (y->parent == z)
            x->parent = y;
        else
        {
            RBTreeTransplant(T, y, y->rchild);
            y->rchild = z->rchild;
            y->rchild->parent = y;
        }
        RBTreeTransplant(T, z, y);
        y->lchild = z->lchild;
        y->lchild->parent = y;
        y->color = z->color;
    }
    if (y_original_color = BLACK)
        RBTreeDeleteFixup(T, x);
    free(y);
}
/*-------------------------------------------------------*/
void RBTreeDeleteFixup(RBTree T, pRBTNode x)  //辅助删除过程
{
    pRBTNode w;
    while ((x != T->Root) && (x->color == BLACK))
    {
        if (x == x->parent->lchild)
        {
            w = x->parent->rchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                LeftRotate(T, x->parent);
                w = x->parent->rchild;
            }
            if (w->lchild->color == BLACK && w->rchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->rchild->color == BLACK)
                {
                    w->lchild->color = BLACK;
                    w->color = RED;
                    RightRotate(T, w);
                    w = x->parent->rchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->rchild->color = BLACK;
                LeftRotate(T, x->parent);
                x = T->Root;
            }
        }
        else
        {
            w = x->parent->lchild;
            if (w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                RightRotate(T, x->parent);
                w = x->parent->lchild;
            }
            if (w->rchild->color == BLACK&&w->lchild->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if (w->lchild->color == BLACK)
                {
                    w->rchild->color = BLACK;
                    w->color = RED;
                    LeftRotate(T, w);
                    w = x->parent->lchild;
                }
                w->color = w->parent->color;
                x->parent->color = BLACK;
                w->lchild->color = BLACK;
                RightRotate(T, x->parent);
                x = T->Root;
            }
        }
    }
    x->color = BLACK;
}
/*-------------------------------------------------------*/
pRBTNode SearchNodeByKey(RBTree T, KeyType key)  //根据关键字查找结点
{
        pRBTNode x = T->Root;
        while (x != T->Nil && key != x->key)
        {
            if (key < x->key)
                x = x->lchild;
            else
                x = x->rchild;
        }
        return x;
}

程序可以运行,但有时候会出错,太累了,这个bug先不找了。

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值