红黑树代码实现

插入元素

情况1:插入结点为根
直接染黑
在这里插入图片描述
情况2:插入结点父亲为黑
不进行任何操作
在这里插入图片描述
情况3:插入结点父亲为红,叔叔为红
爷爷染红,父亲和叔叔染黑,把爷爷视为新结点继续判断
在这里插入图片描述
情况4:插入结点父亲为红,叔叔为黑
情况4-1:LL型
父亲和爷爷右旋,父亲染黑,爷爷染红
在这里插入图片描述
情况4-2:LR型
插入结点和父亲左旋,转化为情况4-1
在这里插入图片描述
情况4-3:RR型
父亲和爷爷左旋,父亲染黑,爷爷染红
在这里插入图片描述
情况4-4:RL型
插入结点与父亲右旋,转化为情况4-3
在这里插入图片描述

删除元素

情况1:删除结点左右孩子均不为空
找到直接前驱,关键字赋值给删除结点,然后将直接前驱(最多有一个不为空的孩子)视为新的删除结点,此时问题被转化为了其它情况

情况2:删除结点为红
此时该结点左右孩子一定为空结点,直接删除该结点

情况3:删除结点为黑,儿子为红
儿子顶替删除结点,然后染红

情况4:删除结点为黑,儿子为黑
情况4最为复杂,单独讨论,此时儿子结点一定为空节点

情况4-1:删除结点是根结点
初始化红黑树

情况4-2:兄弟为红
父亲和兄弟旋转变换,兄弟成为祖父,祖父和父亲颜色对换,将问题转换为其它情况

情况4-3:父亲为黑,兄弟为黑,侄子为黑
兄弟染红将问题转换位其他情况

情况4-4:父亲为红,兄弟为黑,侄子为黑
父亲染黑,兄弟染红

情况4-5:左兄弟为黑,左侄子为红,右侄子为黑
兄弟和兄弟红孩子旋转对换颜色变为其它情况

情况4-6:右兄弟为黑,右侄子为红
父亲和兄弟左旋对换颜色

完整实现代码

#include <stdio.h>
#include <stdlib.h>

//颜色
typedef enum Color {
    red,
    black
} Color;

//红黑树结点
typedef struct RBTNode {
    int key; //关键字
    int color; //颜色
    struct RBTNode *parent; //双亲
    struct RBTNode *lChild; //左孩子
    struct RBTNode *rChild; //右孩子
} RBTNode;

//红黑树
typedef struct RBT {
    RBTNode *root; //根结点
    RBTNode *nil; //引入nil结点
} RBT;

//获取爷爷结点
RBTNode *grandparent(const RBTNode *p) {
    return p->parent->parent;
}

//获取叔叔结点
RBTNode *uncle(const RBTNode *p) {
    if (grandparent(p)->lChild == p->parent) {
        return grandparent(p)->rChild;
    }
    return grandparent(p)->lChild;
}

//获取兄弟结点
RBTNode *brother(const RBTNode *p) {
    if (p->parent->lChild == p) {
        return p->parent->rChild;
    }
    return p->parent->lChild;
}

//获取直接前驱
RBTNode *precursor(const RBT *rbt, RBTNode *p) {
    p = p->lChild;
    while (p->rChild != rbt->nil) {
        p = p->rChild;
    }
    return p;
}

//左旋
void leftRotate(RBT *rbt, RBTNode *p) {
    RBTNode *rChild = p->rChild;
    p->rChild = rChild->lChild;
    if (rChild->lChild != rbt->nil) {
        rChild->lChild->parent = p;
    }
    rChild->parent = p->parent;
    if (p->parent->lChild == p) {
        p->parent->lChild = rChild;
    } else if (p->parent->rChild == p) {
        p->parent->rChild = rChild;
    } else {
        rbt->root = rChild;
    }
    rChild->lChild = p;
    p->parent = rChild;
}

//右旋
void rightRotate(RBT *rbt, RBTNode *p) {
    RBTNode *lChild = p->lChild;
    p->lChild = lChild->rChild;
    if (lChild->rChild != rbt->nil) {
        lChild->rChild->parent = p;
    }
    lChild->parent = p->parent;
    if (p->parent->lChild == p) {
        p->parent->lChild = lChild;
    } else if (p->parent->rChild == p) {
        p->parent->rChild = lChild;
    } else {
        rbt->root = lChild;
    }
    lChild->rChild = p;
    p->parent = lChild;
}

//创建
RBTNode *createRBTNode(int key, Color color, RBTNode *parent, RBTNode *lChild, RBTNode *rChild) {
    RBTNode *node = (RBTNode *) malloc(sizeof(RBTNode));
    node->key = key;
    node->color = color;
    node->parent = parent;
    node->lChild = lChild;
    node->rChild = rChild;
    return node;
}

//初始化
void initRBT(RBT *rbt) {
    rbt->nil = createRBTNode(0, black, NULL, NULL, NULL);
    rbt->nil->parent = rbt->root = rbt->nil;
}

//查找
bool searchRBT(const RBT *rbt, int key, RBTNode **pp) {
    RBTNode *p = *pp = rbt->root;
    while (p != rbt->nil) {
        *pp = p;
        if (p->key > key) {
            p = p->lChild;
        } else if (p->key < key) {
            p = p->rChild;
        } else {
            return true;
        }
    }
    return false;
}

//插入操作后修复
void insertFix(RBT *rbt, RBTNode *p) {
    while (p->parent->color == red) {
        if (p->parent == p->parent->parent->lChild) {
            if (uncle(p)->color == red) {
                p->parent->color = black;
                grandparent(p)->color = red;
                uncle(p)->color = black;
                p = grandparent(p);
            } else {
                if (p == p->parent->rChild) {
                    p = p->parent;
                    leftRotate(rbt, p);
                }
                rightRotate(rbt, grandparent(p));
                p->parent->color = black;
                brother(p)->color = red;
            }
        } else {
            if (uncle(p)->color == red) {
                p->parent->color = black;
                grandparent(p)->color = red;
                uncle(p)->color = black;
                p = grandparent(p);
            } else {
                if (p == p->parent->lChild) {
                    p = p->parent;
                    rightRotate(rbt, p);
                }
                leftRotate(rbt, grandparent(p));
                p->parent->color = black;
                brother(p)->color = red;
            }
        }
    }
    rbt->root->color = black;
}

//插入
void insertRBT(RBT *rbt, int key) {
    RBTNode *p = rbt->nil;
    if (searchRBT(rbt, key, &p)) {
        printf("结点已存在!\n");
        return;
    }
    RBTNode *node = createRBTNode(key, red, p, rbt->nil, rbt->nil);
    if (p == rbt->nil) {
        rbt->root = node;
    } else if (p->key > key) {
        p->lChild = node;
    } else {
        p->rChild = node;
    }
    insertFix(rbt, node);
}

//删除复杂的情况
void deleteDifficult(RBT *rbt, RBTNode *p) {
    if (p->parent == rbt->nil) {
        p->color = black;
        return;
    }
    if (brother(p)->color == red) {
        p->parent->color = red;
        brother(p)->color = black;
        if (p == p->parent->lChild) {
            leftRotate(rbt, p->parent);
        } else {
            rightRotate(rbt, p->parent);
        }
    }
    if (p->parent->color == black && brother(p)->color == black && brother(p)->lChild->color == black &&
        brother(p)->rChild->color == black) {
        brother(p)->color = red;
        deleteDifficult(rbt, p->parent);
    } else if (p->parent->color == red && brother(p)->color == black && brother(p)->lChild->color == black &&
               brother(p)->rChild->color == black) {
        brother(p)->color = red;
        p->parent->color = black;
    } else {
        if (brother(p)->color == black) {
            if (p == p->parent->lChild && brother(p)->lChild->color == red && brother(p)->rChild->color == black) {
                brother(p)->color = red;
                brother(p)->lChild->color = black;
                rightRotate(rbt, brother(p)->lChild);
            } else if (p == p->parent->rChild && brother(p)->lChild->color == black &&
                       brother(p)->rChild->color == red) {
                brother(p)->color = red;
                brother(p)->rChild->color = black;
                leftRotate(rbt, brother(p)->rChild);
            }
        }
        brother(p)->color = p->parent->color;
        p->parent->color = black;
        if (p == p->parent->lChild) {
            brother(p)->rChild->color = black;
            leftRotate(rbt, brother(p));
        } else {
            brother(p)->lChild->color = black;
            rightRotate(rbt, brother(p));
        }
    }
}

//删除只有一个孩子的结点
void deleteOneChild(RBT *rbt, RBTNode *p) {
    RBTNode *child = p->lChild == rbt->nil ? p->rChild : p->lChild;
    if (p->parent == rbt->nil && p->lChild == rbt->nil && p->rChild == rbt->nil) {
        rbt->root = rbt->nil;
    } else if (p->parent == rbt->nil) {
        child->color = black;
        child->parent = rbt->nil;
        rbt->root = child;
    } else {
        if (p->parent->lChild == p) {
            p->parent->lChild = child;
        } else {
            p->parent->rChild = child;
        }
        child->parent = p->parent;
        if (p->color == black) {
            if (child->color == red) {
                child->color = black;
            } else {
                deleteDifficult(rbt, child);
            }
        }
    }
    free(p);
}

//删除
void deleteRBT(RBT *rbt, int key) {
    RBTNode *p = rbt->nil;
    if (!searchRBT(rbt, key, &p)) {
        printf("结点不存在!\n");
        return;
    }
    if (p->lChild != rbt->nil && p->rChild != rbt->nil) {
        p->key = precursor(rbt, p)->key;
        p = precursor(rbt, p);
    }
    deleteOneChild(rbt, p);
}

//中序遍历
void inorderRBT(const RBTNode *p, RBTNode *nil) {
    if (p != nil) {
        inorderRBT(p->lChild, nil);
        printf("%-10d", p->key);
        if (p->color == red) {
            printf("%-10s", "红色");
        } else {
            printf("%-10s", "黑色");
        }
        if (p->lChild != nil) {
            printf("%-10d", p->lChild->key);
        } else {
            printf("%-10s", "无");
        }
        if (p->rChild != nil) {
            printf("%-10d", p->rChild->key);
        } else {
            printf("%-10s", "无");
        }
        if (p->parent != nil) {
            printf("%-10d\n", p->parent->key);
        } else {
            printf("%-10s\n", "无");
        }
        inorderRBT(p->rChild, nil);
    }
}

//测试代码
void test() {
    RBT rbt;
    initRBT(&rbt);
    int sel, key;
    while (true) {
        printf("1.插入数据\n2.删除数据\n3.打印信息\n");
        scanf("%d", &sel);
        switch (sel) {
            case 1: {
                printf("关键字:");
                scanf("%d", &key);
                insertRBT(&rbt, key);
                break;
            }
            case 2: {
                printf("关键字:");
                scanf("%d", &key);
                deleteRBT(&rbt, key);
                break;
            }
            case 3: {
                printf("%-10s%-10s%-10s%-10s%-10s\n", "关键字", "颜色", "左孩子", "右孩子", "双亲");
                inorderRBT(rbt.root, rbt.nil);
                break;
            }
            default:
                return;
        }
        system("pause");
        system("cls");
    }
}

//主函数
int main() {
    test();
    return 0;
}
  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花园宝宝没有天线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值