由于AVL树不适用一些经常修改的结构,这是因为AVL树追求绝对的平衡,所以就有了一种近似平衡的二叉搜索树红黑树,相对而言,降低了插入和旋转的次数,所以在经常进行增删的结构中性能比AVL树更优,而且红黑树实现比较简单,所以实际运用中红黑树更多。
红黑树在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black,它有这些特点:
- 每个结点不是红色就是黑色
- 根节点是黑色的
- 如果一个节点是红色的,则它的两个孩子结点是黑色的
- 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
- 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)
由于红黑树的这些特点,所以红黑树能保证其最长路径中节点个数不会超过最短路径节点个数的两倍
红黑树的插入:
首先按照二叉搜索树的规则插入新节点,如果新节点设为黑色,就会导致根到叶子的路径上有一条路上,多一个额外的黑节点,这个是很难调整的。但是设为红色节点后,可能会导致出现两个连续红色节点的冲突,那么可以通过颜色调换和树旋转来调整
插入红色节点后,分情况讨论当前红黑树的状态
- 其双亲节点的颜色是黑色,没有违反红黑树任何性质,则不需要调整
- 其双亲节点的颜色是红色,约定n为当前节点,p为父节点,g为祖父节点,u为叔叔节点
(2.1) n为红,p为红,g为黑,u存在且为红,则需要将p、u改为黑,g改为红,然后把g当成n,继续向上调整
(2.2) n为红,p为红,g为黑,u不存在/u为黑
(2.2.1) p为g的左孩子,n为p的左孩子,进行右单旋转,同理p为g的右孩子,n为p的右孩子,进行左单旋转
(2.2.2) p为g的左孩子,n为p的右孩子,进行左旋转后变为情况2.2.1,再进行右旋
同理p为g的右孩子,n为p的左孩子,进行右旋转后变为情况2.2.1,再进行左旋
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
|
#include <iostream>
enum COLOR { RED, BLACK };
template <class V> struct RBTNode { RBTNode(const V& data = V()) : _data(data) , _left(nullptr) , _right(nullptr) , _parent(nullptr) , _color(RED) {}
V _data; RBTNode<V>* _left; RBTNode<V>* _right; RBTNode<V>* _parent; COLOR _color; };
template <class V> class _RBTreeIterator { public: typedef RBTNode<V> Node; typedef Node* pNode; typedef _RBTreeIterator<V> Self;
_RBTreeIterator(pNode node) : _node(node) {}
V& operator*() { return _node->_data; }
V* operator->() { return &_node->_data; }
bool operator!=(const Self& it) { return _node != it._node; }
bool operator==(const Self& it) { return _node == it._node; }
Self& operator++() { if (_node->_right) { _node = _node->_right; while (_node->_left) { _node = _node->_left; } } else { pNode parent = _node->_parent; while (parent->_right == _node) { _node = parent; parent = parent->_parent; } if (_node->_right != parent) { _node = parent; } } return *this; }
Self& operator--() { if (_node->_parent->_parent == _node && _node->_color == RED) { _node = _node->_right; } else if (_node->_left) { _node = _node->_left; while (_node->_right) { _node = _node->_right; } } else { pNode parent = _node->_parent; while (parent->_left == _node) { _node = parent; parent = parent->_parent; } _node = parent; } } private: pNode _node; };
template <class K, class V, class KeyOfValue> class RBTree { public: typedef RBTNode<V> Node; typedef Node* pNode; typedef _RBTreeIterator<V> iterator;
RBTree(const V& data = V()) { _header = new Node(data); _header->_left = _header; _header->_right = _header; _header->_parent = nullptr; }
iterator begin() { return iterator(_header->_left); }
iterator end() { return iterator(_header); }
iterator Find(const V& data) { KeyOfValue kov; if (_header == nullptr) { return nullptr; } pNode cur = _header->_parent; while (cur) { if (kov(cur->_data) > kov(data)) { cur = cur->_left; } else if (kov(cur->_data) < kov(data)) { cur = cur->_right; } else { return iterator(cur); } } return iterator(nullptr); }
std::pair<iterator, bool> Insert(const V& data) { if (_header->_parent == nullptr) { pNode root = new Node(data); root->_color = BLACK; root->_parent = _header;
_header->_left = root; _header->_right = root; _header->_parent = root;
return std::make_pair(iterator(root), true); }
pNode cur = _header->_parent; pNode parent = nullptr; KeyOfValue kov; while (cur) { parent = cur; if (kov(cur->_data) > kov(data)) { cur = cur->_left; } else if (kov(cur->_data) < kov(data)) { cur = cur->_right; } else { return std::make_pair(iterator(cur), false); } } cur = new Node(data); pNode newNode = cur; if (kov(parent->_data) > kov(data)) { parent->_left = cur; } else { parent->_right = cur; } cur->_parent = parent;
while (cur != _header->_parent && cur->_parent->_color == RED) { pNode parent = cur->_parent; pNode gParent = parent->_parent;
if (gParent->_left == parent) { pNode uncle = gParent->_right; if (uncle && uncle->_color == RED) { parent->_color = uncle->_color = BLACK; gParent->_color = RED; cur = gParent; } else { if (parent->_right == cur) { RotateLeft(parent); std::swap(cur, parent); } RotateRight(gParent); parent->_color = BLACK; gParent->_color = RED; break; } } else { pNode uncle = gParent->_left; if (uncle && uncle->_color == RED) { uncle->_color = parent->_color = BLACK; gParent->_color = RED; cur = gParent; } else { if (parent->_left == cur) { RotateRight(parent); std::swap(cur, parent); } RotateLeft(gParent); parent->_color = BLACK; gParent->_color = RED; break; } } } _header->_parent->_color = BLACK;
_header->_left = leftMost(); _header->_right = rightMost();
return std::make_pair(iterator(newNode), true); }
pNode leftMost() { pNode cur = _header->_parent; while (cur && cur->_left) { cur = cur->_left; } return cur; }
pNode rightMost() { pNode cur = _header->_parent; while (cur && cur->_right) { cur = cur->_right; } return cur; }
void RotateRight(pNode parent) { pNode subL = parent->_left; pNode subLR = subL->_right;
subL->_right = parent; parent->_left = subLR;
pNode gParent = parent->_parent; parent->_parent = subL; if (subLR) { subLR->_parent = parent; } if (parent != _header->_parent) { if (gParent->_left == parent) { gParent->_left = subL; } else { gParent->_right = subL; } subL->_parent = gParent; } else { _header->_parent = subL; subL->_parent = _header; } }
void RotateLeft(pNode parent) { pNode subR = parent->_right; pNode subRL = subR->_left;
subR->_left = parent; parent->_right = subRL;
if (subRL) { subRL->_parent = parent; } if (parent != _header->_parent) { if (parent->_parent->_left == parent) { parent->_parent->_left = subR; } else { parent->_parent->_right = subR; } subR->_parent = parent->_parent; } else { _header->_parent = subR; subR->_parent = _header; } parent->_parent = subR; }
void _Inorder(pNode root) { if (root) { _Inorder(root->_left); std::cout << root->_data.first << ":" << root->_data.second << " "; _Inorder(root->_right); } }
void Inorder() { _Inorder(_header->_parent); std::cout << std::endl; }
bool isRBTree() { pNode root = _header->_parent; if (root == nullptr) { return true; } if (root->_color == RED) { return false; } int blackCount = 0; pNode cur = root; while (cur) { if (cur->_color == BLACK) { ++blackCount; } cur = cur->_left; } return _isRBTree(root, blackCount, 0); }
bool _isRBTree(pNode root, int blackCount, int curBlackCount) { if (root == nullptr) { if (curBlackCount != blackCount) { return false; } return true; }
if (root->_color == BLACK) { ++curBlackCount; }
if (root->_parent->_color == RED && root->_color == RED) { return false; }
return _isRBTree(root->_left, blackCount, curBlackCount) && _isRBTree(root->_right, blackCount, curBlackCount); } private: pNode _header; };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include "RBTree.hpp"
template <class K, class V> class Map { struct MapKeyOfValue { const K& operator() (const std::pair<K, V>& data) { return data.first; } }; public: typedef typename RBTree<K, std::pair<K, V>, MapKeyOfValue>::iterator iterator;
iterator Find(const K& key) { return _rbt.Find(std::make_pair(key, V())); }
iterator begin() { return _rbt.begin(); }
iterator end() { return _rbt.end(); }
std::pair<iterator, bool> Insert(const std::pair<K, V>& data) { return _rbt.Insert(data); }
V& operator[](const K& key) { std::pair<iterator, bool> ret = _rbt.Insert(std::make_pair(key, V())); return ret.first->second; } private: RBTree<K, std::pair<K, V>, MapKeyOfValue> _rbt; };
template <class K> class Set { struct SetKeyOfValue { const K& operator()(const K& data) { return data; } }; public: typedef _RBTreeIterator<K> iterator;
iterator Find(const K& key) { return _rbt.Find(key); }
iterator begin() { return _rbt.begin(); }
iterator end() { return _rbt.end(); }
std::pair<iterator, bool> Insert(const K& data) { return _rbt.Insert(data); } private: RBTree<K, K, SetKeyOfValue> _rbt; };
|