红黑树
来源:互联网 发布:中国难民政策 知乎 编辑:程序博客网 时间:2024/06/07 23:29
红黑树是一种数据结构,C++的set, map,和linux的内存管理都是用红黑树实现的。红黑树也是一棵二叉查找树,但是因为其自身结构的特点,其本身非常均衡。时间复杂度为O(logn)。因为在每次插入一个节点或者删除一个节点,红黑树都要对此进行调整。
下面先介绍红黑树的特点,红黑树具有以下几个特征:
1.每个节点不是红色就是黑色的;
2.根节点总是黑色的;
3.每个叶节点是黑色的(nil)
4.如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
5.从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
红黑树主要通过三种方式修正树的平衡,变色,左旋和右旋。
左旋和右旋的代码如下:
左旋:
void leftRotate(RBNode *x) { RBNode *y = x->right; x->right = y->left; if (y->left) { y->left->parent = x; } y->parent = x->parent; if (x->parent == nullptr) { root = y; } else if (x == x->parent->left) { x->parent->left = y; } else { x->parent->right = y; } y->left = x; x->parent = y;}
右旋:
void rightRoate(RBNode *y) { RBNode *x = y->left; y->left = x->right; if (x->right) { x->right->parent = y; } x->parent = y->parent; if (y->parent == nullptr) { root = x; } else if (y == y->parent->left) { y->parent->left = x; } else { y->parent->right = x; } x->right = y; y->parent = x;}
变色主要体现在插入和删除节点部分。插入和删除部分比较复杂,我在看书的过程中做了一些笔记。大家可以参考一下:
插入节点平衡调整如下:
删除节点的调整如下:
这两部分的代码如下:
void insertFixUp(RBNode *z) { RBNode *par, *gParent; while(z->parent != NULL && z->parent->color == RED) { par = z->parent; gParent = par->parent; if (par == gParent->left) { RBNode *uncle = gParent->right; if (uncle->color == RED) { par->color = BLACK; uncle->color = BLACK; gParent->color = RED; z = gParent; continue; } else if (z == par->right){ leftRotate(par); RBNode *tmp = par; par = z; z = tmp; } par->color = BLACK; gParent->color = RED; rightRoate(gParent); } else { RBNode *uncle = gParent->left; if (uncle->color == RED) { par->color = BLACK; uncle->color = BLACK; gParent->color = RED; z = gParent; continue; } else if (z == par->left) { rightRoate(par); RBNode* tmp = par; par = z; z = par; } par->color = BLACK; gParent->color = RED; leftRotate(gParent); } root->color = BLACK; }}//插入一个节点void insertNode(RBNode *z) { RBNode *y = nullptr; RBNode *x = root; while(x) { if (z->val < x->val) { x = x->left; } else { x = x->right; } } z->parent = y; if (y == nullptr) { z = root; } else if (z->val < y->val) { y->left = z; } else { y->right = z; } z->setColor(RED); insertFixUp(z);}void deleteFixUp(RBNode *x) { RBNode *other, *par; while ((x == nullptr || x->color == BLACK) && x != root) { par = x->parent; if (x == par->left) { other = par->right; if (other->color == RED) { other->color = BLACK; par->color = RED; leftRotate(par); other = par->right; } if ((other->left == nullptr || other->left->color == BLACK) && (other->right == nullptr && other->right->color == BLACK)) { other->color = RED; x = par; } else if (other->right == nullptr || other->right->color == BLACK) { other->left->color = BLACK; other->color = RED; rightRoate(other); other = par->right; } other->color = par->color; par->color = BLACK; other->right->color = BLACK; leftRotate(par); x = root; break; } else { other = par->left; if (other->color = RED) { other->color = BLACK; par->color = RED; rightRoate(par); other = par->left; } if ((other->left == nullptr || other->left->color == BLACK) && (other->right == nullptr && other->right->color == BLACK)) { other->color = RED; x = par; } else if (other->left == nullptr || other->left->color == BLACK) { other->right->color = BLACK; other->color = RED; leftRotate(other); other = par->left; } other->color = par->color; par->color = BLACK; other->left->color = BLACK; rightRoate(par); x = root; break; } } if (x) { x->color = BLACK; }}//删除一个节点void deleteNode(RBNode *z) { RBNode *successor; if (!z->left || !z->right) { successor = z; } else { successor = z->right; while (successor->left != nullptr) { successor = successor->left; } } RBNode *nexts; if (successor->left) { nexts = successor->left; } else { nexts = successor->right; } if (successor->parent == nullptr) { root = nexts; } else if (successor == successor->parent->left) { successor->parent->left = nexts; } else { successor->parent->right = nexts; } if (successor != z) { z->val = successor->val; } if (successor->color == BLACK) { deleteFixUp(successor); }}
红黑树的结构如下:
const int RED = 1;const int BLACK = 0;class RBNode {public: int val; int color; RBNode *left; RBNode *right; RBNode *parent; RBNode() { val = -1; color = -1; left = nullptr; right = nullptr; parent = nullptr; } void setVal(int val) { val = val; } void setColor(int color) { color = color; }};
阅读全文
0 0
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- 红黑树
- lua 基础知识点
- Django源码学习总结
- Error Number: 1364 Field 'openid' doesn't have a default value startbbs 1.2.3
- python 读文件
- 英语带给我们什么?
- 红黑树
- 【算法】程序猿不写代码是不对的55
- SoC和SIP
- 阿里云日志服务 sdk集成
- C语言趣味程序(5)
- 错误:导入其新的工程时Android studio 停止在 building 'pushstream'Gradle project info界面
- android gson
- 聊聊Spring4.x常用配置(二):EL表达式和资源调用
- Echarts图表———销售漏斗