19#include <QtGui/private/qtguiglobal_p.h>
28 inline Node() : parent(
nullptr), left(
nullptr), right(
nullptr), red(
true) { }
29 inline ~Node() {
if (left)
delete left;
if (right)
delete right;}
37 inline QRBTree() : root(
nullptr), freeList(
nullptr) { }
42 void attachBefore(Node *parent, Node *child);
43 void attachAfter(Node *parent, Node *child);
45 inline Node *front(Node *node)
const;
46 inline Node *back(Node *node)
const;
47 Node *next(Node *node)
const;
48 Node *previous(Node *node)
const;
50 inline void deleteNode(Node *&node);
51 inline Node *newNode();
55 int order(Node *left, Node *right);
56 inline bool validate()
const;
59 void rotateLeft(Node *node);
60 void rotateRight(Node *node);
61 void update(Node *node);
63 inline void attachLeft(Node *parent, Node *child);
64 inline void attachRight(Node *parent, Node *child);
66 int blackDepth(Node *top)
const;
67 bool checkRedBlackProperty(Node *top)
const;
69 void swapNodes(Node *n1, Node *n2);
70 void detach(Node *node);
73 void rebalance(Node *node);
82inline QRBTree<T>::~QRBTree()
87 Node *next = freeList->right;
88 freeList->right =
nullptr;
95inline void QRBTree<T>::clear()
103void QRBTree<T>::rotateLeft(Node *node)
112 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
114 node->right->parent = node->parent;
123 node->right = ref->left;
125 ref->left->parent = node;
144void QRBTree<T>::rotateRight(Node *node)
153 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
155 node->left->parent = node->parent;
157 node->left = ref->right;
159 ref->right->parent = node;
166void QRBTree<T>::update(Node *node)
169 Node *parent = node->parent;
182 Node *grandpa = parent->parent;
185 Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
186 if (uncle && uncle->red) {
189 Q_ASSERT(!grandpa->red);
198 if (node == parent->right && parent == grandpa->left)
199 rotateLeft(node = parent);
200 else if (node == parent->left && parent == grandpa->right)
201 rotateRight(node = parent);
202 parent = node->parent;
204 if (parent == grandpa->left) {
205 rotateRight(grandpa);
218inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
220 Q_ASSERT(!parent->left);
221 parent->left = child;
222 child->parent = parent;
227inline void QRBTree<T>::attachRight(Node *parent, Node *child)
229 Q_ASSERT(!parent->right);
230 parent->right = child;
231 child->parent = parent;
236void QRBTree<T>::attachBefore(Node *parent, Node *child)
239 update(root = child);
241 attachRight(back(root), child);
242 else if (parent->left)
243 attachRight(back(parent->left), child);
245 attachLeft(parent, child);
249void QRBTree<T>::attachAfter(Node *parent, Node *child)
252 update(root = child);
254 attachLeft(front(root), child);
255 else if (parent->right)
256 attachLeft(front(parent->right), child);
258 attachRight(parent, child);
262void QRBTree<T>::swapNodes(Node *n1, Node *n2)
265 if (n1->parent == n2) {
266 n1->parent = n2->parent;
268 }
else if (n2->parent == n1) {
269 n2->parent = n1->parent;
272 qSwap(n1->parent, n2->parent);
275 qSwap(n1->left, n2->left);
276 qSwap(n1->right, n2->right);
277 qSwap(n1->red, n2->red);
280 if (n1->parent->left == n2)
281 n1->parent->left = n1;
283 n1->parent->right = n1;
289 if (n2->parent->left == n1)
290 n2->parent->left = n2;
292 n2->parent->right = n2;
298 n1->left->parent = n1;
300 n1->right->parent = n1;
303 n2->left->parent = n2;
305 n2->right->parent = n2;
309void QRBTree<T>::detach(Node *node)
312 swapNodes(node, front(node->right));
314 Node *child = (node->left ? node->left : node->right);
317 if (child && child->red)
323 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
326 child->parent = node->parent;
327 node->left = node->right = node->parent =
nullptr;
332void QRBTree<T>::rebalance(Node *node)
334 Q_ASSERT(!node->red);
340 Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
344 sibling->red =
false;
345 node->parent->red =
true;
346 if (node == node->parent->left)
347 rotateLeft(node->parent);
349 rotateRight(node->parent);
350 sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
355 Q_ASSERT(!sibling->red);
357 if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
358 bool parentWasRed = node->parent->red;
360 node->parent->red =
false;
369 if (node == node->parent->left) {
370 if (!sibling->right || !sibling->right->red) {
371 Q_ASSERT(sibling->left);
373 sibling->left->red =
false;
374 rotateRight(sibling);
376 sibling = sibling->parent;
379 sibling->red = node->parent->red;
380 node->parent->red =
false;
382 Q_ASSERT(sibling->right->red);
383 sibling->right->red =
false;
384 rotateLeft(node->parent);
386 if (!sibling->left || !sibling->left->red) {
387 Q_ASSERT(sibling->right);
389 sibling->right->red =
false;
392 sibling = sibling->parent;
395 sibling->red = node->parent->red;
396 node->parent->red =
false;
398 Q_ASSERT(sibling->left->red);
399 sibling->left->red =
false;
400 rotateRight(node->parent);
407inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node)
const
415inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node)
const
423typename QRBTree<T>::Node *QRBTree<T>::next(Node *node)
const
426 return front(node->right);
427 while (node->parent && node == node->parent->right)
433typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node)
const
436 return back(node->left);
437 while (node->parent && node == node->parent->left)
443int QRBTree<T>::blackDepth(Node *top)
const
447 int leftDepth = blackDepth(top->left);
448 int rightDepth = blackDepth(top->right);
449 if (leftDepth != rightDepth)
457bool QRBTree<T>::checkRedBlackProperty(Node *top)
const
461 if (top->left && !checkRedBlackProperty(top->left))
463 if (top->right && !checkRedBlackProperty(top->right))
465 return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
469inline bool QRBTree<T>::validate()
const
471 return checkRedBlackProperty(root) && blackDepth(root) != -1;
475inline void QRBTree<T>::deleteNode(Node *&node)
479 node->right = freeList;
485inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
488 Node *node = freeList;
489 freeList = freeList->right;
490 node->parent = node->left = node->right =
nullptr;
500int QRBTree<T>::order(Node *left, Node *right)
502 Q_ASSERT(left && right);
506 QList<Node *> leftAncestors;
507 QList<Node *> rightAncestors;
509 leftAncestors.push_back(left);
513 rightAncestors.push_back(right);
514 right = right->parent;
516 Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
518 while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
519 leftAncestors.pop_back();
520 rightAncestors.pop_back();
523 if (!leftAncestors.empty())
524 return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
526 if (!rightAncestors.empty())
527 return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
530 Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());