【数据结构】:红黑树(RB Tree)
来源:互联网 发布:阿尔玛卡尔玛 知乎 编辑:程序博客网 时间:2024/06/07 16:04
红黑树是近似平衡的二叉搜索树。
红黑树的性质:
1,每个节点不是红色就是黑色
2,根节点必须是黑色
3,没有连续的红节点
4,每条路径上黑色节点数目相等
红黑树保证最长路径不超过最短路径的两倍。那么,为什么满足以上这些条件就能保证呢?
最短路径一定是节点全黑,要保证每条路径的黑节点数量相等,只能在两个黑节点之间添加红节点,所以最长路径不会超过最短路径的两倍。
红黑树保证效率为log2^N
如上图所示是一棵简单的红黑树,红黑树的插入要通过旋转和变色来调节平衡。
当parent是grandfather的左孩子,uncle是grandfather的右孩子时,插入可分为以下情况:
1,叔叔节点存在且为红色
Node* grandfther = parent->_parent; if (parent == grandfther->_left) { Node* uncle = grandfther->_right; if (uncle && uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandfther->_col = RED; cur = grandfther; parent = cur->_parent; }
2,叔叔节点不存在或存在且为黑
将parent变黑,grandfather变红,进行右单旋
else // u 不存在 u黑 { if(cur == parent->_right) // 双旋 { RotateL(parent); swap(cur,parent); } RotateR(grandfther); parent->_col = BLACK; grandfther->_col = RED; break; }
3,cur是parent的右孩子,需要双旋
当parent是grandfather的右时,需要分析的情况还是以上三种,只是方向相反而已。
完整代码:
#pragma once#include<iostream>using namespace std;enum Colour{ RED, BLACK,};template<class K, class V>struct RBTreeNode{ K _key; K _value; RBTreeNode<K, V>* _left; RBTreeNode<K, V>* _right; RBTreeNode<K, V>* _parent; Colour _col; RBTreeNode(const K& key, const V& value) :_key(key) , _value(value) , _left(NULL) , _right(NULL) , _parent(NULL) , _col(RED) {}};template<class K, class V>class RBTree{ typedef RBTreeNode<K, V> Node;public: RBTree() :_root(NULL) {} RBTree(const RBTree<K, V>& tree) { _Copy(tree._root); } ~RBTree() { _Destroy(_root); } RBTree<K, V>& operator = (const RBTree<K, V>& tree) { RBTree<K, V> tmp(tree); swap(_root, tree._root); return *this; } 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->_right; } else if (cur->_key > key) { parent = cur; cur = cur->_left; } 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* grandfather = parent->_parent; if (parent == grandfather->_left) { Node* uncle = grandfather->_right; if (uncle && uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandfather->_col = RED; cur = grandfather; parent = cur->_parent; } else // u 不存在 u黑 { if (cur == parent->_right) // 双旋 { RotateL(parent); swap(cur, parent); } RotateR(grandfather); parent->_col = BLACK; grandfather->_col = RED; break; } } //parent = grandfather->right else if (parent == grandfather->_right) { Node* uncle = grandfather->_left; if (uncle && uncle->_col == RED) { parent->_col = BLACK; uncle->_col = BLACK; grandfather->_col = RED; cur = grandfather; parent = cur->_parent; } else { if (cur == parent->_right) { RotateR(parent); swap(parent, cur); } RotateL(grandfather); parent->_col = BLACK; grandfather->_col = RED; break; } } } _root->_col = BLACK; return true; } void InOrder() { _InOrder(_root); } bool IsBalance() { Node* cur = _root; if (_root == NULL) { return true; } //根节点是黑色 if (_root->_col == RED) { return false; } int BlackNode = 0; //统计最左路径上黑色节点的数量 while (cur) { if (cur->_col == BLACK) { ++BlackNode; } cur = cur->_left; } //一条路径上黑色节点的数量 int num = 0; return _IsBlance(_root, BlackNode, num); }protected: void _Copy(Node* root) { Node* newNode = NULL; Node* cur = root; while (cur) { newNode = new Node(cur->_key, cur->_value); newNode->_left = _Copy(cur->_left); newNode->_right = _Copy(cur->_right); } } void _Destroy(Node* root) { Node* cur = root; if (root == NULL) return; _Destroy(cur->_left); _Destroy(cur->_right); delete cur; cur = NULL; } bool _IsBlance(Node* root, const int BlackNode, int num) { //一条路径已经走完 if (root == NULL) { if (num != BlackNode) { cout << "黑色节点数量不相等" << endl; return false; } else { return true; } } if (root->_col == BLACK) { ++num; } if((root->_col == RED) && (root->_parent) && (root->_parent->_col == RED)) { cout << "有连续的红节点" << root->_key << endl; return false; } return _IsBlance(root->_left, BlackNode, num) && _IsBlance(root->_right, BlackNode, num); } //右旋 void RotateR(Node* parent) { Node* subL = parent->_left; Node* subLR = subL->_right; parent->_left = subLR; if (subLR) subLR->_parent = parent; subL->_right = parent; Node* ppNode = parent->_parent; parent->_parent = subL; if (ppNode == NULL) { _root = subL; subL->_parent = NULL; } else { if (ppNode->_left == parent) { ppNode->_left = subL; } else { ppNode->_right = subL; } subL->_parent = ppNode; } } //左旋 void RotateL(Node* parent) { Node* subR = parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if (subRL) subRL->_parent = parent; subR->_left = parent; Node* ppNode = parent->_parent; parent->_parent = subR; if (ppNode == NULL) { _root = subR; subR->_parent = NULL; } else { if (ppNode->_left == parent) { ppNode->_left = subR; } else { ppNode->_right = subR; } subR->_parent = ppNode; } } void _InOrder(Node* root) { Node* cur = root; if (cur == NULL) return; _InOrder(cur->_left); cout << cur->_key << " "; _InOrder(cur->_right); }private: Node* _root;};void TestRBTree(){ RBTree<int, int> t; int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 }; for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i) { t.Insert(a[i],i); } t.InOrder(); cout << endl; cout << "IsBalance?" << t.IsBalance() << endl;}
我们知道,红黑树是近似平衡的二叉树,那么为什么不直接使用平衡二叉树呢?
原因是红黑树最坏的情况也是log2^N,但它不像平衡二叉树需要严格控制平衡因子,红黑树只需控制节点的颜色,因此它的旋转次数相对于平衡二叉树能少一些,因此,实际中,红黑树的应用更为广泛。
红黑树的应用:
1. C++ STL库 – map
2. Java 库
3. linux内核
4. 其他一些库
阅读全文
1 0
- 数据结构-红黑树(RB-Tree)
- 【数据结构】:红黑树(RB Tree)
- tree, RB-tree(红黑树)
- 数据结构——红黑树(RB-Tree)
- 红黑树原理(RB-Tree Principle)
- RB-tree (红黑树)相关问题
- 红黑树RB-tree
- 红黑树RB-tree
- 红黑树 RB Tree
- RB-tree 红黑树
- STL RB Tree(红黑树)分析
- 非递归学习树结构(六)--RB-Tree(红黑树)
- STL源码剖析——红黑树(RB-tree)
- RB-Tree
- RB-tree
- RB-tree
- RB tree
- [从头学数学] 第261节 Python实现数据结构:红黑树(RB Tree)
- 微软的决绝与决心:拥抱人工智能,布局下一代计算平台
- 人工智能产业要想“弯道超车”,中国只需做到这关键一点
- SVN 更新的时候报“modify-wcprop”出错
- 战火升级,高通将富士康等4家苹果供应商告上法庭
- Python中的条件判断和循环
- 【数据结构】:红黑树(RB Tree)
- android studio向模拟器发送短信
- 智能小车43:avr溶丝位晶振的设置
- 【Wannafly挑战赛2 】B
- 希尔排序
- SSD与YOLO及faster-RCNN的改进特点(目标检测)
- 新手村 顺序与分支 不高兴的津津
- Javaweb-xml基础3(学习笔记)
- 腾讯QQ与长隆集团达成战略合作,推出全球首家QQfamily 智能主题酒店