16class AVL:
public BST<Node, Compare> {
18 using typename BST<Node, Compare>::Key;
27 using BST<Node, Compare>::_cmp;
28 using BST<Node, Compare>::_root;
31 explicit AVL(Compare cmp = Compare()): AVL(nullptr, cmp) {}
32 AVL(
const AVL& other) =
delete;
35 [[nodiscard]]
unsigned int height()
const {
return height(_root); }
44 if (replaced !=
nullptr) {
45 if (replaced->is_left_heavy()) {
46 node->set_left_heavy();
48 else if (replaced->is_right_heavy()) {
49 node->set_right_heavy();
57 for (
auto probe = node; probe !=
nullptr; probe = probe->parent) {
58 auto parent = probe->parent;
59 if (parent ==
nullptr) {
62 auto grand_parent = parent->parent;
64 if (probe == parent->left()) {
65 if (parent->is_left_heavy()) {
66 if (probe->is_right_heavy()) {
67 new_subroot = rotate_left_right(parent, probe);
70 new_subroot = rotate_right(parent, probe);
74 if (parent->is_right_heavy()) {
75 parent->set_balanced();
79 parent->set_left_heavy();
85 if (parent->is_right_heavy()) {
86 if (probe->is_left_heavy()) {
87 new_subroot = rotate_right_left(parent, probe);
90 new_subroot = rotate_left(parent, probe);
94 if (parent->is_left_heavy()) {
95 parent->set_balanced();
99 parent->set_right_heavy();
104 if (grand_parent !=
nullptr) {
105 if (parent == grand_parent->left()) {
106 link_left(grand_parent, new_subroot);
109 link_right(grand_parent, new_subroot);
113 new_subroot->parent =
nullptr;
121 Node* remove(Node* node) {
122 auto remove_report = this->
template BST<Node, Compare>::remove(node);
123 auto substitution = remove_report.substitution;
124 auto new_subroot = remove_report.subtree_child;
125 auto parent = remove_report.subtree_parent;
126 bool is_left_child = remove_report.is_left_child;
128 if (substitution != new_subroot) {
129 if (node->is_left_heavy()) {
130 substitution->set_left_heavy();
132 else if (node->is_right_heavy()) {
133 substitution->set_right_heavy();
136 substitution->set_balanced();
140 while (parent !=
nullptr) {
141 bool sibling_balanced;
142 auto grand_parent = parent->parent;
144 auto sibling = parent->right();
145 if (parent->is_right_heavy()) {
146 sibling_balanced = sibling->is_balanced();
147 if (sibling->is_left_heavy()) {
148 new_subroot = rotate_right_left(parent, sibling);
151 new_subroot = rotate_left(parent, sibling);
155 if (parent->is_balanced()) {
156 parent->set_right_heavy();
159 new_subroot = parent;
160 new_subroot->set_balanced();
161 parent = grand_parent;
162 if (parent !=
nullptr) {
163 is_left_child = (new_subroot == parent->left());
169 auto sibling = parent->left();
170 if (parent->is_left_heavy()) {
171 sibling_balanced = sibling->is_balanced();
172 if (sibling->is_right_heavy()) {
173 new_subroot = rotate_left_right(parent, sibling);
176 new_subroot = rotate_right(parent, sibling);
180 if (parent->is_balanced()) {
181 parent->set_left_heavy();
184 new_subroot = parent;
185 new_subroot->set_balanced();
186 parent = grand_parent;
187 if (parent !=
nullptr) {
188 is_left_child = (new_subroot == parent->left());
193 if (grand_parent !=
nullptr) {
194 if (parent == grand_parent->left()) {
195 link_left(grand_parent, new_subroot);
196 is_left_child =
true;
199 link_right(grand_parent, new_subroot);
200 is_left_child =
false;
204 new_subroot->parent =
nullptr;
207 if (sibling_balanced) {
210 parent = grand_parent;
216 if (_root ==
nullptr) {
217 return { AVL(_cmp), AVL(_cmp),
nullptr };
220 SplitResult split_result { AVL(_root->left(), _cmp), AVL(_root->right(), _cmp), _root };
221 split_result.left.
insert(_root);
228 static AVL merge(AVL&& subtree1, AVL&& subtree2) {
229 auto first_is_less = subtree1._cmp(subtree1._root->key, subtree2._root->key);
230 auto& left = first_is_less ? subtree1 : subtree2;
231 auto& right = first_is_less ? subtree2 : subtree1;
232 auto new_subroot = AVL::_leftmost(right._root);
233 right.remove(new_subroot);
234 new_subroot->parent =
nullptr;
235 const auto left_height = left.height();
236 const auto right_height = right.height();
237 if (left_height > right_height + 1) {
238 auto probe = _rightmost(left._root);
239 int probe_height = height(probe);
240 while (probe_height < right_height) {
241 probe = probe->parent;
242 if (probe->is_left_heavy()) {
250 auto parent = probe->parent;
251 link_left(new_subroot, probe);
252 link_right(new_subroot, right._root);
253 link_right(parent, new_subroot);
254 update_size_path(new_subroot);
255 if (right_height > probe_height) {
256 new_subroot->set_right_heavy();
258 else if (right_height < probe_height) {
259 new_subroot->set_left_heavy();
262 new_subroot->set_balanced();
265 while (parent !=
nullptr) {
266 auto grand_parent = parent->parent;
267 if (parent->is_right_heavy()) {
268 if (new_subroot->is_left_heavy()) {
269 auto node = rotate_right_left(parent, new_subroot);
270 if (grand_parent !=
nullptr) {
271 link_right(grand_parent, node);
274 node->parent =
nullptr;
280 auto node = rotate_left(parent, new_subroot);
281 if (grand_parent !=
nullptr) {
282 link_right(grand_parent, node);
285 node->parent =
nullptr;
288 if (node->is_balanced()) {
292 parent = grand_parent;
296 if (parent->is_left_heavy()) {
297 parent->set_balanced();
300 parent->set_right_heavy();
301 new_subroot = parent;
302 parent = grand_parent;
306 right._root =
nullptr;
307 return std::move(left);
309 if (right_height > left_height + 1) {
310 auto probe = _leftmost(right._root);
311 int probe_height = height(probe);
312 while (probe_height < left_height) {
313 probe = probe->parent;
314 if (probe->is_right_heavy()) {
322 auto parent = probe->parent;
323 link_left(new_subroot, left._root);
324 link_right(new_subroot, probe);
325 link_left(parent, new_subroot);
326 update_size_path(new_subroot);
327 if (probe_height < left_height) {
328 new_subroot->set_left_heavy();
330 else if (probe_height > left_height) {
331 new_subroot->set_right_heavy();
334 new_subroot->set_balanced();
337 while (parent !=
nullptr) {
338 auto grand_parent = parent->parent;
339 if (parent->is_left_heavy()) {
340 if (new_subroot->is_right_heavy()) {
341 auto node = rotate_left_right(parent, new_subroot);
342 if (grand_parent !=
nullptr) {
343 link_left(grand_parent, node);
346 node->parent =
nullptr;
352 auto node = rotate_right(parent, new_subroot);
353 if (grand_parent !=
nullptr) {
354 link_left(grand_parent, node);
357 node->parent =
nullptr;
360 if (node->is_balanced()) {
364 parent = grand_parent;
368 if (parent->is_right_heavy()) {
369 parent->set_balanced();
372 parent->set_left_heavy();
373 new_subroot = parent;
374 parent = grand_parent;
378 left._root =
nullptr;
379 return std::move(right);
382 link_left(new_subroot, left._root);
383 link_right(new_subroot, right._root);
384 update_size(new_subroot);
385 if (left_height > right_height) {
386 new_subroot->set_left_heavy();
388 else if (right_height > left_height) {
389 new_subroot->set_right_heavy();
392 new_subroot->set_balanced();
394 left._root =
nullptr;
395 right._root =
nullptr;
396 return AVL(new_subroot, left._cmp);
400 explicit AVL(Node* root, Compare cmp = Compare()): BST<Node, Compare>(root, cmp) {}
402 using BST<Node, Compare>::link_left;
403 using BST<Node, Compare>::link_right;
404 using BST<Node, Compare>::update_size;
405 using BST<Node, Compare>::update_size_path;
406 using BST<Node, Compare>::_leftmost;
407 using BST<Node, Compare>::_rightmost;
410 static unsigned int height(
const Node* node) {
411 if (node ==
nullptr) {
414 if (node->is_right_heavy()) {
415 return 2 + height(node->left());
417 if (node->is_left_heavy()) {
418 return 2 + height(node->right());
420 return 1 + height(node->right());
423 static Node* rotate_left(Node* parent, Node* child) {
424 link_right(parent, child->left());
425 link_left(child, parent);
430 if (child->is_balanced()) {
431 parent->set_right_heavy();
432 child->set_left_heavy();
435 parent->set_balanced();
436 child->set_balanced();
442 static Node* rotate_right(Node* parent, Node* child) {
443 link_left(parent, child->right());
444 link_right(child, parent);
449 if (child->is_balanced()) {
450 parent->set_left_heavy();
451 child->set_right_heavy();
454 parent->set_balanced();
455 child->set_balanced();
461 static Node* rotate_right_left(Node* parent, Node* child) {
462 auto grand_child = child->left();
464 link_left(child, grand_child->right());
465 link_right(grand_child, child);
466 link_right(parent, grand_child->left());
467 link_left(grand_child, parent);
471 update_size(grand_child);
473 if (grand_child->is_balanced()) {
474 parent->set_balanced();
475 child->set_balanced();
477 else if (grand_child->is_right_heavy()) {
478 parent->set_left_heavy();
479 child->set_balanced();
482 parent->set_balanced();
483 child->set_right_heavy();
485 grand_child->set_balanced();
490 static Node* rotate_left_right(Node* parent, Node* child) {
491 auto grand_child = child->right();
493 link_right(child, grand_child->left());
494 link_left(grand_child, child);
495 link_left(parent, grand_child->right());
496 link_right(grand_child, parent);
500 update_size(grand_child);
502 if (grand_child->is_balanced()) {
503 parent->set_balanced();
504 child->set_balanced();
506 else if (grand_child->is_right_heavy()) {
507 parent->set_balanced();
508 child->set_left_heavy();
511 parent->set_right_heavy();
512 child->set_balanced();
514 grand_child->set_balanced();