红黑树(rbTree)
一种特殊的平衡 二叉排序树,一般用于key,value查找,插入删除查找O(log2n),应用广泛;
定义
- 具有二叉排序树性质
- 每个结点是红的或者黑的,根结点是黑的,每个叶子结点是黑的(一般叶子结点都是隐藏的空结点)
- 如果一个结点是红的,则它的两个儿子都是黑的
- 对每个结点,从该结点到其子孙结点的所有路径上的包含相同数目的黑色结点

| #define RED 0 |
| #define BLACK 1 |
| |
| typedef int KEY_TYPE; |
| |
| |
| #define RBTREE_ENTRY(name, type) \ |
| struct name { |
| struct type *right; \ |
| struct type *left; \ |
| struct type *parent; \ |
| unsigned char color; \ |
| } |
| |
| |
| typedef struct _rbtree_node{ |
| KEY_TYPE key; |
| void *value; |
| |
| #if 1 |
| struct _rbtree_node *right; |
| struct _rbtree_node *left; |
| struct _rbtree_node *parent; |
| unsigned char color; |
| #else |
| RBTREE_ENTRY(, rbtree_node) node; |
| #endif |
| |
| } rbtree_node; |
| |
| typedef struct _rbtree{ |
| struct rbtree_node *root; |
| struct rbtree_node *nil; |
| } rbtree; |
红黑树的旋转
- 和AVL树一样,红黑树的旋转,只出现在插入和删除结点数据的时候
- 旋转的过程中不会修改结点的颜色,只会修改三对指针的值,比较好理解
| |
| void rbtree_left_rotate(rbtree *T, rbtree_node *x){ |
| rbtree_node *y=x->right; |
| |
| |
| x->right = y->left; |
| if(y->left != T->nil){ |
| y->left->parent = x; |
| } |
| |
| |
| y->parent = x->parent; |
| if(x->parent == T->nil){ |
| T->root = y; |
| }else if(x == x->parent->left){ |
| x->parent->left = y; |
| }else{ |
| x->parent->right = y; |
| } |
| |
| |
| y->left = x; |
| x->parent = y; |
| } |
| |
| |
| |
| void rbtree_left_rotate(rbtree *T, rbtree_node *y){ |
| rbtree_node *x = y->left; |
| |
| |
| y->left = x->right; |
| if(x->right != T->nil){ |
| x->right->parent = y; |
| } |
| |
| |
| x->parent = y->parent; |
| if(y->parent == T->nil){ |
| T->root = x; |
| }else if(y == y->parent->right){ |
| y->parent->right = x; |
| }else{ |
| y->parent->left = x; |
| } |
| |
| |
| x->left = y; |
| y->parent = x; |
| } |
红黑树的插入与调整
- 红黑树在插入一个结点之前,它已经是一颗红黑树
- 红黑树插入结点为红色,在整个插入过程中插入节点的颜色不会改变,始终为红色
- 插入后打破红黑树平衡(红黑树的定义),会通过旋转和改变parent节点的颜色,重新恢复平衡
| |
| void rbtree_insert_fixup(rbtree *T, rbtree_node *z){ |
| |
| while(z->parent->color == RED){ |
| if(z->parent == z->parent->parent->left){ |
| rbtree_node *y = z->parent->parent->right; |
| if(y->color == RED){ |
| z->parent->color = BLACK; |
| y->color = BLACK; |
| z->parent->parent->color = RED; |
| |
| z = z->parent->parent; |
| } else { |
| if(z == z->parent->right){ |
| z = z->parent; |
| rbtree_left_rotate(T, z); |
| } |
| |
| z->parent->color = BLACK; |
| z->parent->parent->color = RED; |
| rbtree_right_rotate(T, z->parent->parent); |
| } |
| } |
| } |
| } |
| |
| |
| void retree_insert(rbtree *T, rebtree_node *z){ |
| rbtree_node *y = T->nil; |
| rbtree_node *x = T->root; |
| |
| while (x != T->nil){ |
| y = x; |
| if(z->key < x->key){ |
| x=x->left; |
| }else if(z->key > x->key){ |
| x=x->right; |
| }else{ |
| |
| return; |
| } |
| } |
| |
| if(y == T->nil){ |
| T->root=z; |
| }else{ |
| if(y->key > z->key){ |
| y->left = z; |
| }else{ |
| y->right = z; |
| } |
| } |
| |
| z->parent=y; |
| z->left=T->nil; |
| z->right=T->nil; |
| z->color=RED; |
| |
| rbtree_insert_fixup(T, z); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
2019-10-09 word2vec词向量简述