RB-tree 红黑树
来源:互联网 发布:万网解析域名 编辑:程序博客网 时间:2024/06/06 08:24
除AVL树外,还有RBtree也是经常用到的平衡二叉搜索树
RBtree必须满足以下四条规则:
1.每个节点不是红色就是黑色
2.根节点为黑色
3.如果一个节点是红色,则它的 子节点是黑色的(即没有连续的红节点)
4.任一节点至NULL(树尾端)的任何路径,所含黑节点数必须相同
那AVL和RBtree有什么区别
AVltree 是严格平衡的二叉搜索树,其复杂度接近lgN,旋转多,维护起来麻烦,但是更加直观
RBree 是近似平衡的二叉搜索树,其复杂度一定小于2*(LgN),但是曾有人做过大量试验证明,红黑树的效率仍能达到lgN,旋转则较少,维护起来简单,今后项目什么的一定会优先RBtree,其比较抽象
插入操作
注意:cur为当前节点 P为父节点 g为祖父节点 u为父亲的兄弟节点即叔叔节点
状况1:该树为空树,直接插入根结点的位置,违反性质1,把节点颜色有红改为黑即可。
状况2:插入节点N的父节点P为黑色,不违反任何性质,无需做任何修改。
接下来是真正需要调整的状况了
状况3:当cur为红,P为红,g为黑,u存在且为红
先将p,u变为黑色,g改成红,然后把cur给g,继续向上搜索
状况4: cur为红,P为红,g为黑,u不存在/u为黑(cur为p的左节点)
状态5:cur为红,P为红,g为黑,u不存在/u为黑(cur为p的右节点)
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转,则转换成了情况2
删除操作
状况1:cur的兄弟b是红色的。
情况2:cur的兄弟b是黑色的,且cur的俩个孩子都是黑色的。
b变为红色后经过b节点的路径的黑节点数目也减少了1,那个从P出发到其叶子节点到所有路径所包含的黑节点数目相等了。但是这个数目比之前少了1,因为左右子树中的黑节点数目都减少了。P是他父节点g的一个孩子,那么由g到其叶子节点的黑节点数目就不相等了,所以说没有结束,需把P当做新的起始点开始向上检索。
情形3:P为红(S一定为黑),S的孩子们都为黑。
情形4:P任意色,b为黑,cur是P的左孩子,b的右孩子bR为红,b的左孩子任意(或者是cur是P的右孩子,b的左孩子为红,b的右孩子任意)。
P、b旋转有变色,等于给cur这边加了一个黑节点,P位置(是位置而不是P)的颜色不变,b这边少了一个黑节点;bR有红变黑,b这边又增加了一个黑节点;这样一来又恢复了平衡
情形5:P任意色,b为黑,cur是P的左孩子,b的左孩子bL为红,b的右孩子bR为黑(或者cur是P的右孩子,b的右孩子为红,b的左孩子为黑)。
这如果你按情形4的操作的话,由于bR本来就是黑色,无法弥补由于P、b的变换(旋转)给b这边造成的损失!所以没先对b、SL进行变换之后就变为情形4的情况了
#pragma once#include<stdio.h>#include<iostream>using namespace std;enum Color{ RED, BLACK,};template<class K, class V>struct RBTreeNode{ RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; K _key; V _value; Color _col; RBTreeNode(const K& key, const V& value) :_left(NULL) , _right(NULL) , _parent(NULL) , _key(key) , _value(value) , _col(RED) {}};template<class K,class V>class RBTree{ typedef RBTreeNode<K,V> Node;public: RBTree() :_root(NULL) {} bool Insert(const K& key,const V& value) { if (_root == NULL) { _root = new Node(key,value); _root->_col = BLACK; return true; } Node* parent = NULL; Node* cur = _root; while (cur) { if (cur->_key > key) { parent = cur; cur = cur->_left; } else if (cur->_key < key) { parent = cur; cur = cur->_right; } else { return false; } } //找到插入位置 cur = new Node(key, value); if (parent->_key < key) { parent->_right = cur; cur->_parent = parent; } else { parent->_left = cur; cur->_parent = parent; } while (parent&&parent->_col == RED) { Node* grandparent = parent->_parent; if (parent == grandparent->_left) { Node* uncle = grandparent->_right; if (uncle&&uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandparent->_col = RED; cur = grandparent; parent = cur->_parent; } else //uncle不存在,或uncle为黑色 { if (cur == parent->_right) { RotateL(parent); swap(parent,cur); } RotateR(grandparent); parent->_col = BLACK; grandparent->_col = RED; break; } } else//parent == grandparent->_right { Node* uncle = grandparent->_left; if (uncle&&uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandparent->_col = RED; } else//uncle不存在或者为黑色 { if (cur == parent->_left) { RotateR(parent); swap(parent, cur); } RotateL(grandparent); parent->_col = BLACK; grandparent->_col = RED; break; } } } _root->_col = BLACK; return true; } void RotateL(Node* parent) { Node* subR = parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if (subRL) { subRL->_parent = parent; } subR->_left = parent; Node* parentparent = parent->_parent; parent->_parent = subR; if (parentparent==NULL) { _root = subR; } else { if (parent == parentparent->_left) { parentparent->_left = subR; subR->_parent = parentparent; } else { parentparent->_right = subR; subR->_parent = parentparent; } } } void RotateR(Node* parent) { Node* subL = parent->_left; Node* subLR = subL->_right; parent->_left = subLR; if (subLR) { subLR->_parent = parent; } subL->_right = parent; Node* parentparent = parent->_parent; parent->_parent = subL; if (parentparent == NULL) { _root = subL; _root->_parent = NULL; } else { if (parent == parentparent->_left) { parentparent->_left = subL; subL->_parent = parentparent; } else { parentparent->_right = subL; subL->_parent = parentparent; } } } void InOrder() { _InOrder(_root); cout << endl; } void _InOrder(Node* root) { if (root == NULL) return; _InOrder(root->_left); cout<<root->_key<<" "; _InOrder(root->_right); } bool IsBalance() { if (_root == NULL) { return true; } if (_root&&_root->_col==RED) { return false; } int BlackNum = 0; Node* left = _root; while (left) { if (left->_col == BLACK) { ++BlackNum; } left = left->_left; } int num = 0; return _IsBalance(_root, num, BlackNum); } bool _IsBalance(Node* root, int num, const int blackNum) { if (root == NULL) { return true; } if (root->_col == RED&&root->_parent->_col == RED) { cout<<"存在连续的红节点"<<root->_key<<endl; return false; } if (root->_col == BLACK) { ++num; } // num 是根节点到当前节点黑色节点的数量 if (root->_left == NULL && root->_right == NULL) { if (num != blackNum) { //cout<<"黑色节点的数量不相等"<<root->_key<<endl; return false; } else { return true; } } return _IsBalance(root->_left, num, blackNum) && _IsBalance(root->_right, num, blackNum); }private: Node* _root;};void TestRBTree(){ RBTree<int, int> t; int a[] = {16, 3, 7, 11, 9, 26, 18, 14, 15}; //int a[] = {4, 2, 6, 1, 3, 5, 15, 7, 16, 14}; for (size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i) { t.Insert(a[i], i); } t.InOrder(); cout<<"IsBalance?"<<t.IsBalance()<<endl;}
- 红黑树RB-tree
- 红黑树RB-tree
- 红黑树 RB Tree
- RB-tree 红黑树
- tree, RB-tree(红黑树)
- STL RB Tree(红黑树)分析
- 数据结构-红黑树(RB-Tree)
- 【数据结构】:红黑树(RB Tree)
- RB-Tree
- RB-tree
- RB-tree
- RB tree
- 数据结构——红黑树(RB-Tree)
- 红黑树原理(RB-Tree Principle)
- RB-tree (红黑树)相关问题
- RB-tree(zz)
- STL中的RB-tree
- STL-RB Tree
- HDU 1257 最少拦截系统 (贪心)
- 【NOIP2017提高A组冲刺11.4】总结
- Eclipse java开发问 Maven使用问题
- 反射
- 数据链路层服务
- RB-tree 红黑树
- synchronized关键字
- NOIP考前总结与反思
- op的交流分析
- 大数据用户画像方法与实践
- wait notify
- 支持向量机(二)
- 171103-函数程序联系(2)【连续第十一天】
- rn iOS真机调试 采坑系列