55 inline bool validate()
const;
58 void rotateLeft(Node *node);
59 void rotateRight(Node *node);
60 void update(Node *node);
62 inline void attachLeft(Node *parent, Node *child);
63 inline void attachRight(Node *parent, Node *child);
65 int blackDepth(Node *top)
const;
66 bool checkRedBlackProperty(Node *top)
const;
68 void swapNodes(Node *n1, Node *n2);
69 void detach(Node *node);
72 void rebalance(Node *node);
81inline QRBTree<T>::~QRBTree()
86 Node *next = freeList->right;
87 freeList->right =
nullptr;
94inline void QRBTree<T>::clear()
102void QRBTree<T>::rotateLeft(Node *node)
111 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
113 node->right->parent = node->parent;
122 node->right = ref->left;
124 ref->left->parent = node;
143void QRBTree<T>::rotateRight(Node *node)
152 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
154 node->left->parent = node->parent;
156 node->left = ref->right;
158 ref->right->parent = node;
165void QRBTree<T>::update(Node *node)
168 Node *parent = node->parent;
181 Node *grandpa = parent->parent;
184 Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
185 if (uncle && uncle->red) {
188 Q_ASSERT(!grandpa->red);
197 if (node == parent->right && parent == grandpa->left)
198 rotateLeft(node = parent);
199 else if (node == parent->left && parent == grandpa->right)
200 rotateRight(node = parent);
201 parent = node->parent;
203 if (parent == grandpa->left) {
204 rotateRight(grandpa);
217inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
219 Q_ASSERT(!parent->left);
220 parent->left = child;
221 child->parent = parent;
226inline void QRBTree<T>::attachRight(Node *parent, Node *child)
228 Q_ASSERT(!parent->right);
229 parent->right = child;
230 child->parent = parent;
235void QRBTree<T>::attachBefore(Node *parent, Node *child)
238 update(root = child);
240 attachRight(back(root), child);
241 else if (parent->left)
242 attachRight(back(parent->left), child);
244 attachLeft(parent, child);
248void QRBTree<T>::attachAfter(Node *parent, Node *child)
251 update(root = child);
253 attachLeft(front(root), child);
254 else if (parent->right)
255 attachLeft(front(parent->right), child);
257 attachRight(parent, child);
261void QRBTree<T>::swapNodes(Node *n1, Node *n2)
264 if (n1->parent == n2) {
265 n1->parent = n2->parent;
267 }
else if (n2->parent == n1) {
268 n2->parent = n1->parent;
271 qSwap(n1->parent, n2->parent);
274 qSwap(n1->left, n2->left);
275 qSwap(n1->right, n2->right);
276 qSwap(n1->red, n2->red);
279 if (n1->parent->left == n2)
280 n1->parent->left = n1;
282 n1->parent->right = n1;
288 if (n2->parent->left == n1)
289 n2->parent->left = n2;
291 n2->parent->right = n2;
297 n1->left->parent = n1;
299 n1->right->parent = n1;
302 n2->left->parent = n2;
304 n2->right->parent = n2;
308void QRBTree<T>::detach(Node *node)
311 swapNodes(node, front(node->right));
313 Node *child = (node->left ? node->left : node->right);
316 if (child && child->red)
322 Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
325 child->parent = node->parent;
326 node->left = node->right = node->parent =
nullptr;
331void QRBTree<T>::rebalance(Node *node)
333 Q_ASSERT(!node->red);
339 Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
343 sibling->red =
false;
344 node->parent->red =
true;
345 if (node == node->parent->left)
346 rotateLeft(node->parent);
348 rotateRight(node->parent);
349 sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
354 Q_ASSERT(!sibling->red);
356 if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
357 bool parentWasRed = node->parent->red;
359 node->parent->red =
false;
368 if (node == node->parent->left) {
369 if (!sibling->right || !sibling->right->red) {
370 Q_ASSERT(sibling->left);
372 sibling->left->red =
false;
373 rotateRight(sibling);
375 sibling = sibling->parent;
378 sibling->red = node->parent->red;
379 node->parent->red =
false;
381 Q_ASSERT(sibling->right->red);
382 sibling->right->red =
false;
383 rotateLeft(node->parent);
385 if (!sibling->left || !sibling->left->red) {
386 Q_ASSERT(sibling->right);
388 sibling->right->red =
false;
391 sibling = sibling->parent;
394 sibling->red = node->parent->red;
395 node->parent->red =
false;
397 Q_ASSERT(sibling->left->red);
398 sibling->left->red =
false;
399 rotateRight(node->parent);
406inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node)
const
414inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node)
const
422typename QRBTree<T>::Node *QRBTree<T>::next(Node *node)
const
425 return front(node->right);
426 while (node->parent && node == node->parent->right)
432typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node)
const
435 return back(node->left);
436 while (node->parent && node == node->parent->left)
442int QRBTree<T>::blackDepth(Node *top)
const
446 int leftDepth = blackDepth(top->left);
447 int rightDepth = blackDepth(top->right);
448 if (leftDepth != rightDepth)
456bool QRBTree<T>::checkRedBlackProperty(Node *top)
const
460 if (top->left && !checkRedBlackProperty(top->left))
462 if (top->right && !checkRedBlackProperty(top->right))
464 return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
468inline bool QRBTree<T>::validate()
const
470 return checkRedBlackProperty(root) && blackDepth(root) != -1;
499int QRBTree<T>::order(Node *left, Node *right)
501 Q_ASSERT(left && right);
505 QList<Node *> leftAncestors;
506 QList<Node *> rightAncestors;
508 leftAncestors.push_back(left);
512 rightAncestors.push_back(right);
513 right = right->parent;
515 Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
517 while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
518 leftAncestors.pop_back();
519 rightAncestors.pop_back();
522 if (!leftAncestors.empty())
523 return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
525 if (!rightAncestors.empty())
526 return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
529 Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());