数据结构-红黑树(RBTree)
来源:互联网 发布:国际网络交易平台 编辑:程序博客网 时间:2024/05/29 05:12
红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black。
通过对任何一条从根到叶子简单 路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似于平衡。
红黑树是满足下面红黑性质的二叉搜索树
1. 每个节点,不是红色就是黑色的
1. 每个节点,不是红色就是黑色的
2. 根节点是黑色的
3. 如果一个节点是红色的,则它的两个子节点是黑色的
4. 对每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点。
插入的几种情况
ps:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点
ps:cur为当前节点,p为父节点,g为祖父节点,u为叔叔节点
1.第一种情况 cur为红,p为红,g为黑,u存在且为红
则将p,u改为黑,g改为红,然后把g当成cur,继续向上调整。
2.第二种情况 cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的左孩子,则进行右单旋转;
相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转
p、g变色--p变黑,g变红
3.第三种情况
cur为红,p为红,g为黑,u不存在/u为黑
cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;
相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转
则转换成了情况2
4.第四种情况
为空树或者只有一个根节点
主要代码:
#pragma onceenum Color{RED,BLACK};template <typename K, typename V>struct RBTreeNode{K _key;V _value;Color _col;RBTreeNode<K, V>* _left;RBTreeNode<K, V>* _right;RBTreeNode<K, V>* _parent;RBTreeNode(const K& key, const V& value):_key(key), _value(value), _left(NULL), _right(NULL), _parent(NULL), _col(RED){}};template<typename K, typename V>class RBTree{typedef RBTreeNode<K,V> Node;public:RBTree():_root(NULL){}pair<Node* ,bool> Insert(const K& key, const V& value){if (_root == NULL){_root = new Node(key, value);_root->_col = BLACK;return make_pair(_root,true);}Node* cur = _root;Node* parent = NULL;while (cur){if (key < cur->_key){parent = cur;cur = cur->_left;}else if (key>cur->_key){parent = cur;cur = cur->_right;}else{return make_pair(cur, false);}}cur = new Node(key, value);if (parent->_key < key){parent->_right = cur;cur->_parent = parent;}else{parent->_left = cur;cur->_parent = parent;} //到这块表示插入完成,然后进行调整Node* newcur = cur;while (parent && parent->_col == RED){Node* grandparent = parent->_parent;if (grandparent->_left == parent){Node* uncle = grandparent->_right;//1.if (uncle && uncle->_col == RED){uncle->_col = parent->_col = BLACK;grandparent->_col = RED;cur = grandparent;parent = cur->_parent;}else // 2,3 (2为单旋,3为双旋){if (cur == parent->_left){//右单旋RotateR(grandparent);}else{//左右双旋RotateLR(grandparent);swap(parent, cur);}parent->_col = BLACK;grandparent->_col = RED;break;}}else{Node* uncle = grandparent->_left;if (uncle && uncle->_col == RED){uncle->_col = parent->_col = BLACK;grandparent->_col = RED;cur = grandparent;parent = cur->_parent;}else // 2,3 (2为单旋,3为双旋){if (cur == parent->_right){//右单旋RotateL(grandparent);}else{//左右双旋RotateRL(grandparent);swap(parent, cur);}parent->_col = BLACK;grandparent->_col = RED;break;}}}_root->_col = BLACK;return make_pair(newcur, true);}V& operator[](const K& key){pair<Node*, bool> ret;ret = Insert(key,V());return ret.first->_value;}bool IsRBTree(){if (_root && _root->_col == RED)return false;size_t k = 0;size_t num = 0;Node* cur = _root;while (cur){if (cur->_col == BLACK)++k;cur = cur->_left;}return CheckColor(_root) && CheckBlackNum(_root, k, num);}protected:bool CheckColor(Node* root){if (root == NULL)return true;if (root->_col == RED && root->_parent->_col == RED)return false;return CheckColor(root->_left) && CheckColor(root->_right);}bool CheckBlackNum(Node* root, const size_t k, size_t num){if (root == NULL){return k == num;}if (root->_col == BLACK)num++;return CheckBlackNum(root->_left, k, num) && CheckBlackNum(root->_right, k, num);}void RotateL(Node* grandparent) //左单旋{Node* subR = grandparent->_right;Node* subRL = subR->_left;grandparent->_right = subRL;if (subRL)subRL->_parent = grandparent;subR->_left = grandparent;Node* ppNode = grandparent->_parent;grandparent->_parent = subR;subR->_parent = ppNode;if (ppNode == NULL){_root = subR;}else{if (ppNode->_left == grandparent){ppNode->_left = subR;}else{ppNode->_right = subR;}}}void RotateR(Node* grandparent) //右单旋{Node* subL = grandparent->_left;Node* subLR = subL->_right;grandparent->_left = subLR;if (subLR)subLR->_parent = grandparent;subL->_right = grandparent;Node* ppNode = grandparent->_parent;grandparent->_parent = subL;subL->_parent = ppNode;if (ppNode == NULL){_root = subL;}else{if (ppNode->_left == grandparent){ppNode->_left = subL;}else{ppNode->_right = subL;}}}void RotateRL(Node* grandparent){RotateR(grandparent->_right);RotateL(grandparent);}void RotateLR(Node* grandparent){RotateL(grandparent->_left);RotateR(grandparent);}private:Node* _root;};
0 0
- 数据结构-红黑树(RBTree)
- 【c++/数据结构】红黑树-RBTree
- 【数据结构】中的红黑树-RBTree
- 使用内核数据结构:红黑树 rbtree
- 红黑树(RBtree)
- 红黑树(RBTree)
- RBTree(红黑树)
- Kernel数据结构移植(list和rbtree)
- 红黑树(RBTree)的实现
- 红黑树-RBTree
- RBTree红黑树
- RBTree----红黑树
- RBTree(红黑树)
- 红黑树--RBTree
- 红黑树【RBTree】
- 算法编程_红黑树(RBTree)
- 红黑树(RBTree)之插入结点图解
- 红黑树(RBTree)之删除结点图解
- Python实战(二)—— urllib2 下载网页的方式总结
- 读写分离实现
- c# 最大公约数 最小公倍数
- SELinux初探
- Failed sending reply to debugger: Broken pipe
- 数据结构-红黑树(RBTree)
- 插入排序算法
- ORM进阶之Hibernate 简介及框架搭
- Android 线程之间的通信——Handler
- 中科爱讯WiFi探针的功能用途与解决方案
- Spring系列(2)--为什么需要动态代理
- 微服务(Microservice)那点事
- iOS导航栏隐藏的情况下设置状态栏颜色
- go error panic deffer recover