2 * Copyright 2003-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * Distributed under the terms of the MIT License.
7 #include <util/AVLTreeBase.h>
11 # include <KernelExport.h>
15 # define CHECK_FAILED(message...) panic(message)
20 # define CHECK_FAILED(message...) \
22 fprintf(stderr, message); \
23 fprintf(stderr, "\n"); \
24 debugger("AVLTreeBase check failed"); \
27 # define CHECK_FAILED(message...) dprintf(message)
32 // maximal height of a tree
33 static const int kMaxAVLTreeHeight
= 32;
36 // #pragma mark - AVLTreeCompare
39 AVLTreeCompare::~AVLTreeCompare()
44 // #pragma mark - AVLTreeBase
47 AVLTreeBase::AVLTreeBase(AVLTreeCompare
* compare
)
55 AVLTreeBase::~AVLTreeBase()
61 AVLTreeBase::MakeEmpty()
69 AVLTreeBase::LeftMost(AVLTreeNode
* node
) const
81 AVLTreeBase::RightMost(AVLTreeNode
* node
) const
93 AVLTreeBase::Previous(AVLTreeNode
* node
) const
96 // The previous node cannot be in the right subtree.
98 // We have a left subtree, so go to the right-most node.
103 // No left subtree: Backtrack our path and stop, where we
104 // took the right branch.
105 AVLTreeNode
* previous
;
109 } while (node
&& previous
== node
->left
);
118 AVLTreeBase::Next(AVLTreeNode
* node
) const
121 // The next node cannot be in the left subtree.
123 // We have a right subtree, so go to the left-most node.
128 // No right subtree: Backtrack our path and stop, where we
129 // took the left branch.
130 AVLTreeNode
* previous
;
134 } while (node
&& previous
== node
->right
);
143 AVLTreeBase::Find(const void* key
) const
145 AVLTreeNode
* node
= fRoot
;
148 int cmp
= fCompare
->CompareKeyNode(key
, node
);
163 AVLTreeBase::FindClosest(const void* key
, bool less
) const
165 AVLTreeNode
* node
= fRoot
;
166 AVLTreeNode
* parent
= NULL
;
169 int cmp
= fCompare
->CompareKeyNode(key
, node
);
180 // not found: try to get close
181 if (!node
&& parent
) {
183 int expectedCmp
= (less
? 1 : -1);
184 int cmp
= fCompare
->CompareKeyNode(key
, node
);
185 if (cmp
!= expectedCmp
) {
186 // The node's value is less although we were asked for a greater
187 // value, or the other way around. We need to iterate to the next
188 // node in the respective direction. If there is no node, we fail.
190 return Previous(node
);
200 AVLTreeBase::Insert(AVLTreeNode
* nodeToInsert
)
202 int result
= _Insert(nodeToInsert
);
217 AVLTreeBase::Remove(const void* key
)
220 AVLTreeNode
* node
= fRoot
;
222 int cmp
= fCompare
->CompareKeyNode(key
, node
);
242 AVLTreeBase::Remove(AVLTreeNode
* node
)
244 switch (_Remove(node
)) {
256 AVLTreeBase::CheckTree() const
259 _CheckTree(NULL
, fRoot
, nodeCount
);
260 if (nodeCount
!= fNodeCount
) {
261 CHECK_FAILED("AVLTreeBase::CheckTree(): node count mismatch: %d vs %d",
262 nodeCount
, fNodeCount
);
268 AVLTreeBase::_RotateRight(AVLTreeNode
** nodeP
)
271 AVLTreeNode
* node
= *nodeP
;
272 AVLTreeNode
* left
= node
->left
;
276 left
->parent
= node
->parent
;
277 node
->left
= left
->right
;
279 left
->right
->parent
= node
;
283 // adjust the balance factors
285 if (left
->balance_factor
>= 0)
286 node
->balance_factor
++;
288 node
->balance_factor
+= 1 - left
->balance_factor
;
291 if (node
->balance_factor
<= 0)
292 left
->balance_factor
++;
294 left
->balance_factor
+= node
->balance_factor
+ 1;
299 AVLTreeBase::_RotateLeft(AVLTreeNode
** nodeP
)
302 AVLTreeNode
* node
= *nodeP
;
303 AVLTreeNode
* right
= node
->right
;
307 right
->parent
= node
->parent
;
308 node
->right
= right
->left
;
310 right
->left
->parent
= node
;
312 node
->parent
= right
;
314 // adjust the balance factors
316 if (right
->balance_factor
<= 0)
317 node
->balance_factor
--;
319 node
->balance_factor
-= right
->balance_factor
+ 1;
322 if (node
->balance_factor
>= 0)
323 right
->balance_factor
--;
325 right
->balance_factor
+= node
->balance_factor
- 1;
330 AVLTreeBase::_BalanceInsertLeft(AVLTreeNode
** node
)
332 if ((*node
)->balance_factor
< LEFT
) {
333 // tree is left heavy
334 AVLTreeNode
** left
= &(*node
)->left
;
335 if ((*left
)->balance_factor
== LEFT
) {
346 if ((*node
)->balance_factor
== BALANCED
)
349 return HEIGHT_CHANGED
;
354 AVLTreeBase::_BalanceInsertRight(AVLTreeNode
** node
)
356 if ((*node
)->balance_factor
> RIGHT
) {
357 // tree is right heavy
358 AVLTreeNode
** right
= &(*node
)->right
;
359 if ((*right
)->balance_factor
== RIGHT
) {
370 if ((*node
)->balance_factor
== BALANCED
)
373 return HEIGHT_CHANGED
;
378 AVLTreeBase::_Insert(AVLTreeNode
* nodeToInsert
)
385 node_info stack
[kMaxAVLTreeHeight
];
386 node_info
* top
= stack
;
387 const node_info
* const bottom
= stack
;
388 AVLTreeNode
** node
= &fRoot
;
390 // find insertion point
392 int cmp
= fCompare
->CompareNodes(nodeToInsert
, *node
);
393 if (cmp
== 0) // duplicate node
399 node
= &(*node
)->left
;
402 node
= &(*node
)->right
;
409 *node
= nodeToInsert
;
410 nodeToInsert
->left
= NULL
;
411 nodeToInsert
->right
= NULL
;
412 nodeToInsert
->balance_factor
= BALANCED
;
416 nodeToInsert
->parent
= NULL
;
418 (*node
)->parent
= *top
[-1].node
;
421 int result
= HEIGHT_CHANGED
;
422 while (result
== HEIGHT_CHANGED
&& top
!= bottom
) {
427 (*node
)->balance_factor
--;
428 result
= _BalanceInsertLeft(node
);
431 (*node
)->balance_factor
++;
432 result
= _BalanceInsertRight(node
);
441 AVLTreeBase::_BalanceRemoveLeft(AVLTreeNode
** node
)
443 int result
= HEIGHT_CHANGED
;
445 if ((*node
)->balance_factor
> RIGHT
) {
446 // tree is right heavy
447 AVLTreeNode
** right
= &(*node
)->right
;
448 if ((*right
)->balance_factor
== RIGHT
) {
451 } else if ((*right
)->balance_factor
== BALANCED
) {
460 } else if ((*node
)->balance_factor
== RIGHT
)
468 AVLTreeBase::_BalanceRemoveRight(AVLTreeNode
** node
)
470 int result
= HEIGHT_CHANGED
;
472 if ((*node
)->balance_factor
< LEFT
) {
473 // tree is left heavy
474 AVLTreeNode
** left
= &(*node
)->left
;
475 if ((*left
)->balance_factor
== LEFT
) {
478 } else if ((*left
)->balance_factor
== BALANCED
) {
487 } else if ((*node
)->balance_factor
== LEFT
)
495 AVLTreeBase::_RemoveRightMostChild(AVLTreeNode
** node
, AVLTreeNode
** foundNode
)
497 AVLTreeNode
** stack
[kMaxAVLTreeHeight
];
498 AVLTreeNode
*** top
= stack
;
499 const AVLTreeNode
* const* const* const bottom
= stack
;
502 while ((*node
)->right
) {
505 node
= &(*node
)->right
;
508 // found the rightmost child: remove it
509 // the found node might have a left child: replace the node with the
512 AVLTreeNode
* left
= (*node
)->left
;
514 left
->parent
= (*node
)->parent
;
516 (*foundNode
)->left
= NULL
;
517 (*foundNode
)->parent
= NULL
;
520 int result
= HEIGHT_CHANGED
;
521 while (result
== HEIGHT_CHANGED
&& top
!= bottom
) {
524 (*node
)->balance_factor
--;
525 result
= _BalanceRemoveRight(node
);
533 AVLTreeBase::_Remove(AVLTreeNode
* node
)
539 AVLTreeNode
* parent
= node
->parent
;
540 bool isLeft
= (parent
&& parent
->left
== node
);
542 = (parent
? (isLeft
? &parent
->left
: &parent
->right
) : &fRoot
);
543 int result
= HEIGHT_CHANGED
;
544 AVLTreeNode
* replace
= NULL
;
546 if (node
->left
&& node
->right
) {
547 // node has two children
548 result
= _RemoveRightMostChild(&node
->left
, &replace
);
549 replace
->parent
= parent
;
550 replace
->left
= node
->left
;
551 replace
->right
= node
->right
;
552 if (node
->left
) // check necessary, if node->left == replace
553 node
->left
->parent
= replace
;
554 node
->right
->parent
= replace
;
555 replace
->balance_factor
= node
->balance_factor
;
558 if (result
== HEIGHT_CHANGED
) {
559 replace
->balance_factor
++;
560 result
= _BalanceRemoveLeft(nodeP
);
562 } else if (node
->left
) {
563 // node has only left child
564 replace
= node
->left
;
565 replace
->parent
= parent
;
566 replace
->balance_factor
= node
->balance_factor
+ 1;
568 } else if (node
->right
) {
569 // node has only right child
570 replace
= node
->right
;
571 replace
->parent
= node
->parent
;
572 replace
->balance_factor
= node
->balance_factor
- 1;
582 while (result
== HEIGHT_CHANGED
&& parent
) {
584 parent
= node
->parent
;
585 bool oldIsLeft
= isLeft
;
586 isLeft
= (parent
&& parent
->left
== node
);
587 nodeP
= (parent
? (isLeft
? &parent
->left
: &parent
->right
) : &fRoot
);
590 node
->balance_factor
++;
591 result
= _BalanceRemoveLeft(nodeP
);
594 node
->balance_factor
--;
595 result
= _BalanceRemoveRight(nodeP
);
604 AVLTreeBase::_CheckTree(AVLTreeNode
* parent
, AVLTreeNode
* node
,
605 int& _nodeCount
) const
612 if (parent
!= node
->parent
) {
613 CHECK_FAILED("AVLTreeBase::_CheckTree(): node %p parent mismatch: "
614 "%p vs %p", node
, parent
, node
->parent
);
618 int leftDepth
= _CheckTree(node
, node
->left
, leftNodeCount
);
621 int rightDepth
= _CheckTree(node
, node
->right
, rightNodeCount
);
623 int balance
= rightDepth
- leftDepth
;
624 if (balance
< LEFT
|| balance
> RIGHT
) {
625 CHECK_FAILED("AVLTreeBase::_CheckTree(): unbalanced subtree: %p", node
);
626 } else if (balance
!= node
->balance_factor
) {
627 CHECK_FAILED("AVLTreeBase::_CheckTree(): subtree %p balance mismatch: "
628 "%d vs %d", node
, balance
, node
->balance_factor
);
631 _nodeCount
= leftNodeCount
+ rightNodeCount
+ 1;
632 return std::max(leftDepth
, rightDepth
) + 1;