A Python parser for MediaWiki wikicode https://mwparserfromhell.readthedocs.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

811 lines
26 KiB

  1. /*
  2. * avl_tree.c - intrusive, nonrecursive AVL tree data structure (self-balancing
  3. * binary search tree), implementation file
  4. *
  5. * Written in 2014-2016 by Eric Biggers <ebiggers3@gmail.com>
  6. * Slight changes for compatibility by Ben Kurtovic <ben.kurtovic@gmail.com>
  7. *
  8. * To the extent possible under law, the author(s) have dedicated all copyright
  9. * and related and neighboring rights to this software to the public domain
  10. * worldwide via the Creative Commons Zero 1.0 Universal Public Domain
  11. * Dedication (the "CC0").
  12. *
  13. * This software is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the CC0 for more details.
  16. *
  17. * You should have received a copy of the CC0 along with this software; if not
  18. * see <http://creativecommons.org/publicdomain/zero/1.0/>.
  19. */
  20. #define false 0
  21. #define true 1
  22. typedef int bool;
  23. #include "avl_tree.h"
  24. /* Returns the left child (sign < 0) or the right child (sign > 0) of the
  25. * specified AVL tree node.
  26. * Note: for all calls of this, 'sign' is constant at compilation time,
  27. * so the compiler can remove the conditional. */
  28. static AVL_INLINE struct avl_tree_node *
  29. avl_get_child(const struct avl_tree_node *parent, int sign)
  30. {
  31. if (sign < 0) {
  32. return parent->left;
  33. } else {
  34. return parent->right;
  35. }
  36. }
  37. static AVL_INLINE struct avl_tree_node *
  38. avl_tree_first_or_last_in_order(const struct avl_tree_node *root, int sign)
  39. {
  40. const struct avl_tree_node *first = root;
  41. if (first) {
  42. while (avl_get_child(first, +sign)) {
  43. first = avl_get_child(first, +sign);
  44. }
  45. }
  46. return (struct avl_tree_node *) first;
  47. }
  48. /* Starts an in-order traversal of the tree: returns the least-valued node, or
  49. * NULL if the tree is empty. */
  50. struct avl_tree_node *
  51. avl_tree_first_in_order(const struct avl_tree_node *root)
  52. {
  53. return avl_tree_first_or_last_in_order(root, -1);
  54. }
  55. /* Starts a *reverse* in-order traversal of the tree: returns the
  56. * greatest-valued node, or NULL if the tree is empty. */
  57. struct avl_tree_node *
  58. avl_tree_last_in_order(const struct avl_tree_node *root)
  59. {
  60. return avl_tree_first_or_last_in_order(root, 1);
  61. }
  62. static AVL_INLINE struct avl_tree_node *
  63. avl_tree_next_or_prev_in_order(const struct avl_tree_node *node, int sign)
  64. {
  65. const struct avl_tree_node *next;
  66. if (avl_get_child(node, +sign)) {
  67. for (next = avl_get_child(node, +sign); avl_get_child(next, -sign);
  68. next = avl_get_child(next, -sign)) {
  69. }
  70. } else {
  71. for (next = avl_get_parent(node); next && node == avl_get_child(next, +sign);
  72. node = next, next = avl_get_parent(next)) {
  73. }
  74. }
  75. return (struct avl_tree_node *) next;
  76. }
  77. /* Continues an in-order traversal of the tree: returns the next-greatest-valued
  78. * node, or NULL if there is none. */
  79. struct avl_tree_node *
  80. avl_tree_next_in_order(const struct avl_tree_node *node)
  81. {
  82. return avl_tree_next_or_prev_in_order(node, 1);
  83. }
  84. /* Continues a *reverse* in-order traversal of the tree: returns the
  85. * previous-greatest-valued node, or NULL if there is none. */
  86. struct avl_tree_node *
  87. avl_tree_prev_in_order(const struct avl_tree_node *node)
  88. {
  89. return avl_tree_next_or_prev_in_order(node, -1);
  90. }
  91. /* Starts a postorder traversal of the tree. */
  92. struct avl_tree_node *
  93. avl_tree_first_in_postorder(const struct avl_tree_node *root)
  94. {
  95. const struct avl_tree_node *first = root;
  96. if (first) {
  97. while (first->left || first->right) {
  98. first = first->left ? first->left : first->right;
  99. }
  100. }
  101. return (struct avl_tree_node *) first;
  102. }
  103. /* Continues a postorder traversal of the tree. @prev will not be deferenced as
  104. * it's allowed that its memory has been freed; @prev_parent must be its saved
  105. * parent node. Returns NULL if there are no more nodes (i.e. @prev was the
  106. * root of the tree). */
  107. struct avl_tree_node *
  108. avl_tree_next_in_postorder(const struct avl_tree_node *prev,
  109. const struct avl_tree_node *prev_parent)
  110. {
  111. const struct avl_tree_node *next = prev_parent;
  112. if (next && prev == next->left && next->right) {
  113. for (next = next->right; next->left || next->right;
  114. next = next->left ? next->left : next->right) {
  115. }
  116. }
  117. return (struct avl_tree_node *) next;
  118. }
  119. /* Sets the left child (sign < 0) or the right child (sign > 0) of the
  120. * specified AVL tree node.
  121. * Note: for all calls of this, 'sign' is constant at compilation time,
  122. * so the compiler can remove the conditional. */
  123. static AVL_INLINE void
  124. avl_set_child(struct avl_tree_node *parent, int sign, struct avl_tree_node *child)
  125. {
  126. if (sign < 0) {
  127. parent->left = child;
  128. } else {
  129. parent->right = child;
  130. }
  131. }
  132. /* Sets the parent and balance factor of the specified AVL tree node. */
  133. static AVL_INLINE void
  134. avl_set_parent_balance(struct avl_tree_node *node,
  135. struct avl_tree_node *parent,
  136. int balance_factor)
  137. {
  138. node->parent_balance = (uintptr_t) parent | (balance_factor + 1);
  139. }
  140. /* Sets the parent of the specified AVL tree node. */
  141. static AVL_INLINE void
  142. avl_set_parent(struct avl_tree_node *node, struct avl_tree_node *parent)
  143. {
  144. node->parent_balance = (uintptr_t) parent | (node->parent_balance & 3);
  145. }
  146. /* Returns the balance factor of the specified AVL tree node --- that is, the
  147. * height of its right subtree minus the height of its left subtree. */
  148. static AVL_INLINE int
  149. avl_get_balance_factor(const struct avl_tree_node *node)
  150. {
  151. return (int) (node->parent_balance & 3) - 1;
  152. }
  153. /* Adds @amount to the balance factor of the specified AVL tree node.
  154. * The caller must ensure this still results in a valid balance factor
  155. * (-1, 0, or 1). */
  156. static AVL_INLINE void
  157. avl_adjust_balance_factor(struct avl_tree_node *node, int amount)
  158. {
  159. node->parent_balance += amount;
  160. }
  161. static AVL_INLINE void
  162. avl_replace_child(struct avl_tree_node **root_ptr,
  163. struct avl_tree_node *parent,
  164. struct avl_tree_node *old_child,
  165. struct avl_tree_node *new_child)
  166. {
  167. if (parent) {
  168. if (old_child == parent->left) {
  169. parent->left = new_child;
  170. } else {
  171. parent->right = new_child;
  172. }
  173. } else {
  174. *root_ptr = new_child;
  175. }
  176. }
  177. /*
  178. * Template for performing a single rotation ---
  179. *
  180. * sign > 0: Rotate clockwise (right) rooted at A:
  181. *
  182. * P? P?
  183. * | |
  184. * A B
  185. * / \ / \
  186. * B C? => D? A
  187. * / \ / \
  188. * D? E? E? C?
  189. *
  190. * (nodes marked with ? may not exist)
  191. *
  192. * sign < 0: Rotate counterclockwise (left) rooted at A:
  193. *
  194. * P? P?
  195. * | |
  196. * A B
  197. * / \ / \
  198. * C? B => A D?
  199. * / \ / \
  200. * E? D? C? E?
  201. *
  202. * This updates pointers but not balance factors!
  203. */
  204. static AVL_INLINE void
  205. avl_rotate(struct avl_tree_node **const root_ptr,
  206. struct avl_tree_node *const A,
  207. const int sign)
  208. {
  209. struct avl_tree_node *const B = avl_get_child(A, -sign);
  210. struct avl_tree_node *const E = avl_get_child(B, +sign);
  211. struct avl_tree_node *const P = avl_get_parent(A);
  212. avl_set_child(A, -sign, E);
  213. avl_set_parent(A, B);
  214. avl_set_child(B, +sign, A);
  215. avl_set_parent(B, P);
  216. if (E) {
  217. avl_set_parent(E, A);
  218. }
  219. avl_replace_child(root_ptr, P, A, B);
  220. }
  221. /*
  222. * Template for performing a double rotation ---
  223. *
  224. * sign > 0: Rotate counterclockwise (left) rooted at B, then
  225. * clockwise (right) rooted at A:
  226. *
  227. * P? P? P?
  228. * | | |
  229. * A A E
  230. * / \ / \ / \
  231. * B C? => E C? => B A
  232. * / \ / \ / \ / \
  233. * D? E B G? D? F?G? C?
  234. * / \ / \
  235. * F? G? D? F?
  236. *
  237. * (nodes marked with ? may not exist)
  238. *
  239. * sign < 0: Rotate clockwise (right) rooted at B, then
  240. * counterclockwise (left) rooted at A:
  241. *
  242. * P? P? P?
  243. * | | |
  244. * A A E
  245. * / \ / \ / \
  246. * C? B => C? E => A B
  247. * / \ / \ / \ / \
  248. * E D? G? B C? G?F? D?
  249. * / \ / \
  250. * G? F? F? D?
  251. *
  252. * Returns a pointer to E and updates balance factors. Except for those
  253. * two things, this function is equivalent to:
  254. * avl_rotate(root_ptr, B, -sign);
  255. * avl_rotate(root_ptr, A, +sign);
  256. *
  257. * See comment in avl_handle_subtree_growth() for explanation of balance
  258. * factor updates.
  259. */
  260. static AVL_INLINE struct avl_tree_node *
  261. avl_do_double_rotate(struct avl_tree_node **const root_ptr,
  262. struct avl_tree_node *const B,
  263. struct avl_tree_node *const A,
  264. const int sign)
  265. {
  266. struct avl_tree_node *const E = avl_get_child(B, +sign);
  267. struct avl_tree_node *const F = avl_get_child(E, -sign);
  268. struct avl_tree_node *const G = avl_get_child(E, +sign);
  269. struct avl_tree_node *const P = avl_get_parent(A);
  270. const int e = avl_get_balance_factor(E);
  271. avl_set_child(A, -sign, G);
  272. avl_set_parent_balance(A, E, ((sign * e >= 0) ? 0 : -e));
  273. avl_set_child(B, +sign, F);
  274. avl_set_parent_balance(B, E, ((sign * e <= 0) ? 0 : -e));
  275. avl_set_child(E, +sign, A);
  276. avl_set_child(E, -sign, B);
  277. avl_set_parent_balance(E, P, 0);
  278. if (G) {
  279. avl_set_parent(G, A);
  280. }
  281. if (F) {
  282. avl_set_parent(F, B);
  283. }
  284. avl_replace_child(root_ptr, P, A, E);
  285. return E;
  286. }
  287. /*
  288. * This function handles the growth of a subtree due to an insertion.
  289. *
  290. * @root_ptr
  291. * Location of the tree's root pointer.
  292. *
  293. * @node
  294. * A subtree that has increased in height by 1 due to an insertion.
  295. *
  296. * @parent
  297. * Parent of @node; must not be NULL.
  298. *
  299. * @sign
  300. * -1 if @node is the left child of @parent;
  301. * +1 if @node is the right child of @parent.
  302. *
  303. * This function will adjust @parent's balance factor, then do a (single
  304. * or double) rotation if necessary. The return value will be %true if
  305. * the full AVL tree is now adequately balanced, or %false if the subtree
  306. * rooted at @parent is now adequately balanced but has increased in
  307. * height by 1, so the caller should continue up the tree.
  308. *
  309. * Note that if %false is returned, no rotation will have been done.
  310. * Indeed, a single node insertion cannot require that more than one
  311. * (single or double) rotation be done.
  312. */
  313. static AVL_INLINE bool
  314. avl_handle_subtree_growth(struct avl_tree_node **const root_ptr,
  315. struct avl_tree_node *const node,
  316. struct avl_tree_node *const parent,
  317. const int sign)
  318. {
  319. int old_balance_factor, new_balance_factor;
  320. old_balance_factor = avl_get_balance_factor(parent);
  321. if (old_balance_factor == 0) {
  322. avl_adjust_balance_factor(parent, sign);
  323. /* @parent is still sufficiently balanced (-1 or +1
  324. * balance factor), but must have increased in height.
  325. * Continue up the tree. */
  326. return false;
  327. }
  328. new_balance_factor = old_balance_factor + sign;
  329. if (new_balance_factor == 0) {
  330. avl_adjust_balance_factor(parent, sign);
  331. /* @parent is now perfectly balanced (0 balance factor).
  332. * It cannot have increased in height, so there is
  333. * nothing more to do. */
  334. return true;
  335. }
  336. /* @parent is too left-heavy (new_balance_factor == -2) or
  337. * too right-heavy (new_balance_factor == +2). */
  338. /* Test whether @node is left-heavy (-1 balance factor) or
  339. * right-heavy (+1 balance factor).
  340. * Note that it cannot be perfectly balanced (0 balance factor)
  341. * because here we are under the invariant that @node has
  342. * increased in height due to the insertion. */
  343. if (sign * avl_get_balance_factor(node) > 0) {
  344. /* @node (B below) is heavy in the same direction @parent
  345. * (A below) is heavy.
  346. *
  347. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  348. * The comment, diagram, and equations below assume sign < 0.
  349. * The other case is symmetric!
  350. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  351. *
  352. * Do a clockwise rotation rooted at @parent (A below):
  353. *
  354. * A B
  355. * / \ / \
  356. * B C? => D A
  357. * / \ / \ / \
  358. * D E? F? G?E? C?
  359. * / \
  360. * F? G?
  361. *
  362. * Before the rotation:
  363. * balance(A) = -2
  364. * balance(B) = -1
  365. * Let x = height(C). Then:
  366. * height(B) = x + 2
  367. * height(D) = x + 1
  368. * height(E) = x
  369. * max(height(F), height(G)) = x.
  370. *
  371. * After the rotation:
  372. * height(D) = max(height(F), height(G)) + 1
  373. * = x + 1
  374. * height(A) = max(height(E), height(C)) + 1
  375. * = max(x, x) + 1 = x + 1
  376. * balance(B) = 0
  377. * balance(A) = 0
  378. */
  379. avl_rotate(root_ptr, parent, -sign);
  380. /* Equivalent to setting @parent's balance factor to 0. */
  381. avl_adjust_balance_factor(parent, -sign); /* A */
  382. /* Equivalent to setting @node's balance factor to 0. */
  383. avl_adjust_balance_factor(node, -sign); /* B */
  384. } else {
  385. /* @node (B below) is heavy in the direction opposite
  386. * from the direction @parent (A below) is heavy.
  387. *
  388. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  389. * The comment, diagram, and equations below assume sign < 0.
  390. * The other case is symmetric!
  391. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  392. *
  393. * Do a counterblockwise rotation rooted at @node (B below),
  394. * then a clockwise rotation rooted at @parent (A below):
  395. *
  396. * A A E
  397. * / \ / \ / \
  398. * B C? => E C? => B A
  399. * / \ / \ / \ / \
  400. * D? E B G? D? F?G? C?
  401. * / \ / \
  402. * F? G? D? F?
  403. *
  404. * Before the rotation:
  405. * balance(A) = -2
  406. * balance(B) = +1
  407. * Let x = height(C). Then:
  408. * height(B) = x + 2
  409. * height(E) = x + 1
  410. * height(D) = x
  411. * max(height(F), height(G)) = x
  412. *
  413. * After both rotations:
  414. * height(A) = max(height(G), height(C)) + 1
  415. * = x + 1
  416. * balance(A) = balance(E{orig}) >= 0 ? 0 : -balance(E{orig})
  417. * height(B) = max(height(D), height(F)) + 1
  418. * = x + 1
  419. * balance(B) = balance(E{orig} <= 0) ? 0 : -balance(E{orig})
  420. *
  421. * height(E) = x + 2
  422. * balance(E) = 0
  423. */
  424. avl_do_double_rotate(root_ptr, node, parent, -sign);
  425. }
  426. /* Height after rotation is unchanged; nothing more to do. */
  427. return true;
  428. }
  429. /* Rebalance the tree after insertion of the specified node. */
  430. void
  431. avl_tree_rebalance_after_insert(struct avl_tree_node **root_ptr,
  432. struct avl_tree_node *inserted)
  433. {
  434. struct avl_tree_node *node, *parent;
  435. bool done;
  436. inserted->left = NULL;
  437. inserted->right = NULL;
  438. node = inserted;
  439. /* Adjust balance factor of new node's parent.
  440. * No rotation will need to be done at this level. */
  441. parent = avl_get_parent(node);
  442. if (!parent) {
  443. return;
  444. }
  445. if (node == parent->left) {
  446. avl_adjust_balance_factor(parent, -1);
  447. } else {
  448. avl_adjust_balance_factor(parent, +1);
  449. }
  450. if (avl_get_balance_factor(parent) == 0) {
  451. /* @parent did not change in height. Nothing more to do. */
  452. return;
  453. }
  454. /* The subtree rooted at @parent increased in height by 1. */
  455. do {
  456. /* Adjust balance factor of next ancestor. */
  457. node = parent;
  458. parent = avl_get_parent(node);
  459. if (!parent) {
  460. return;
  461. }
  462. /* The subtree rooted at @node has increased in height by 1. */
  463. if (node == parent->left) {
  464. done = avl_handle_subtree_growth(root_ptr, node, parent, -1);
  465. } else {
  466. done = avl_handle_subtree_growth(root_ptr, node, parent, +1);
  467. }
  468. } while (!done);
  469. }
  470. /*
  471. * This function handles the shrinkage of a subtree due to a deletion.
  472. *
  473. * @root_ptr
  474. * Location of the tree's root pointer.
  475. *
  476. * @parent
  477. * A node in the tree, exactly one of whose subtrees has decreased
  478. * in height by 1 due to a deletion. (This includes the case where
  479. * one of the child pointers has become NULL, since we can consider
  480. * the "NULL" subtree to have a height of 0.)
  481. *
  482. * @sign
  483. * +1 if the left subtree of @parent has decreased in height by 1;
  484. * -1 if the right subtree of @parent has decreased in height by 1.
  485. *
  486. * @left_deleted_ret
  487. * If the return value is not NULL, this will be set to %true if the
  488. * left subtree of the returned node has decreased in height by 1,
  489. * or %false if the right subtree of the returned node has decreased
  490. * in height by 1.
  491. *
  492. * This function will adjust @parent's balance factor, then do a (single
  493. * or double) rotation if necessary. The return value will be NULL if
  494. * the full AVL tree is now adequately balanced, or a pointer to the
  495. * parent of @parent if @parent is now adequately balanced but has
  496. * decreased in height by 1. Also in the latter case, *left_deleted_ret
  497. * will be set.
  498. */
  499. static AVL_INLINE struct avl_tree_node *
  500. avl_handle_subtree_shrink(struct avl_tree_node **const root_ptr,
  501. struct avl_tree_node *parent,
  502. const int sign,
  503. bool *const left_deleted_ret)
  504. {
  505. struct avl_tree_node *node;
  506. int old_balance_factor, new_balance_factor;
  507. old_balance_factor = avl_get_balance_factor(parent);
  508. if (old_balance_factor == 0) {
  509. /* Prior to the deletion, the subtree rooted at
  510. * @parent was perfectly balanced. It's now
  511. * unbalanced by 1, but that's okay and its height
  512. * hasn't changed. Nothing more to do. */
  513. avl_adjust_balance_factor(parent, sign);
  514. return NULL;
  515. }
  516. new_balance_factor = old_balance_factor + sign;
  517. if (new_balance_factor == 0) {
  518. /* The subtree rooted at @parent is now perfectly
  519. * balanced, whereas before the deletion it was
  520. * unbalanced by 1. Its height must have decreased
  521. * by 1. No rotation is needed at this location,
  522. * but continue up the tree. */
  523. avl_adjust_balance_factor(parent, sign);
  524. node = parent;
  525. } else {
  526. /* @parent is too left-heavy (new_balance_factor == -2) or
  527. * too right-heavy (new_balance_factor == +2). */
  528. node = avl_get_child(parent, sign);
  529. /* The rotations below are similar to those done during
  530. * insertion (see avl_handle_subtree_growth()), so full
  531. * comments are not provided. The only new case is the
  532. * one where @node has a balance factor of 0, and that is
  533. * commented. */
  534. if (sign * avl_get_balance_factor(node) >= 0) {
  535. avl_rotate(root_ptr, parent, -sign);
  536. if (avl_get_balance_factor(node) == 0) {
  537. /*
  538. * @node (B below) is perfectly balanced.
  539. *
  540. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  541. * The comment, diagram, and equations
  542. * below assume sign < 0. The other case
  543. * is symmetric!
  544. * @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  545. *
  546. * Do a clockwise rotation rooted at
  547. * @parent (A below):
  548. *
  549. * A B
  550. * / \ / \
  551. * B C? => D A
  552. * / \ / \ / \
  553. * D E F? G?E C?
  554. * / \
  555. * F? G?
  556. *
  557. * Before the rotation:
  558. * balance(A) = -2
  559. * balance(B) = 0
  560. * Let x = height(C). Then:
  561. * height(B) = x + 2
  562. * height(D) = x + 1
  563. * height(E) = x + 1
  564. * max(height(F), height(G)) = x.
  565. *
  566. * After the rotation:
  567. * height(D) = max(height(F), height(G)) + 1
  568. * = x + 1
  569. * height(A) = max(height(E), height(C)) + 1
  570. * = max(x + 1, x) + 1 = x + 2
  571. * balance(A) = -1
  572. * balance(B) = +1
  573. */
  574. /* A: -2 => -1 (sign < 0)
  575. * or +2 => +1 (sign > 0)
  576. * No change needed --- that's the same as
  577. * old_balance_factor. */
  578. /* B: 0 => +1 (sign < 0)
  579. * or 0 => -1 (sign > 0) */
  580. avl_adjust_balance_factor(node, -sign);
  581. /* Height is unchanged; nothing more to do. */
  582. return NULL;
  583. } else {
  584. avl_adjust_balance_factor(parent, -sign);
  585. avl_adjust_balance_factor(node, -sign);
  586. }
  587. } else {
  588. node = avl_do_double_rotate(root_ptr, node, parent, -sign);
  589. }
  590. }
  591. parent = avl_get_parent(node);
  592. if (parent) {
  593. *left_deleted_ret = (node == parent->left);
  594. }
  595. return parent;
  596. }
  597. /* Swaps node X, which must have 2 children, with its in-order successor, then
  598. * unlinks node X. Returns the parent of X just before unlinking, without its
  599. * balance factor having been updated to account for the unlink. */
  600. static AVL_INLINE struct avl_tree_node *
  601. avl_tree_swap_with_successor(struct avl_tree_node **root_ptr,
  602. struct avl_tree_node *X,
  603. bool *left_deleted_ret)
  604. {
  605. struct avl_tree_node *Y, *ret;
  606. Y = X->right;
  607. if (!Y->left) {
  608. /*
  609. * P? P? P?
  610. * | | |
  611. * X Y Y
  612. * / \ / \ / \
  613. * A Y => A X => A B?
  614. * / \ / \
  615. * (0) B? (0) B?
  616. *
  617. * [ X unlinked, Y returned ]
  618. */
  619. ret = Y;
  620. *left_deleted_ret = false;
  621. } else {
  622. struct avl_tree_node *Q;
  623. do {
  624. Q = Y;
  625. Y = Y->left;
  626. } while (Y->left);
  627. /*
  628. * P? P? P?
  629. * | | |
  630. * X Y Y
  631. * / \ / \ / \
  632. * A ... => A ... => A ...
  633. * | | |
  634. * Q Q Q
  635. * / / /
  636. * Y X B?
  637. * / \ / \
  638. * (0) B? (0) B?
  639. *
  640. *
  641. * [ X unlinked, Q returned ]
  642. */
  643. Q->left = Y->right;
  644. if (Q->left) {
  645. avl_set_parent(Q->left, Q);
  646. }
  647. Y->right = X->right;
  648. avl_set_parent(X->right, Y);
  649. ret = Q;
  650. *left_deleted_ret = true;
  651. }
  652. Y->left = X->left;
  653. avl_set_parent(X->left, Y);
  654. Y->parent_balance = X->parent_balance;
  655. avl_replace_child(root_ptr, avl_get_parent(X), X, Y);
  656. return ret;
  657. }
  658. /*
  659. * Removes an item from the specified AVL tree.
  660. *
  661. * @root_ptr
  662. * Location of the AVL tree's root pointer. Indirection is needed
  663. * because the root node may change if the tree needed to be rebalanced
  664. * because of the deletion or if @node was the root node.
  665. *
  666. * @node
  667. * Pointer to the `struct avl_tree_node' embedded in the item to
  668. * remove from the tree.
  669. *
  670. * Note: This function *only* removes the node and rebalances the tree.
  671. * It does not free any memory, nor does it do the equivalent of
  672. * avl_tree_node_set_unlinked().
  673. */
  674. void
  675. avl_tree_remove(struct avl_tree_node **root_ptr, struct avl_tree_node *node)
  676. {
  677. struct avl_tree_node *parent;
  678. bool left_deleted = false;
  679. if (node->left && node->right) {
  680. /* @node is fully internal, with two children. Swap it
  681. * with its in-order successor (which must exist in the
  682. * right subtree of @node and can have, at most, a right
  683. * child), then unlink @node. */
  684. parent = avl_tree_swap_with_successor(root_ptr, node, &left_deleted);
  685. /* @parent is now the parent of what was @node's in-order
  686. * successor. It cannot be NULL, since @node itself was
  687. * an ancestor of its in-order successor.
  688. * @left_deleted has been set to %true if @node's
  689. * in-order successor was the left child of @parent,
  690. * otherwise %false. */
  691. } else {
  692. struct avl_tree_node *child;
  693. /* @node is missing at least one child. Unlink it. Set
  694. * @parent to @node's parent, and set @left_deleted to
  695. * reflect which child of @parent @node was. Or, if
  696. * @node was the root node, simply update the root node
  697. * and return. */
  698. child = node->left ? node->left : node->right;
  699. parent = avl_get_parent(node);
  700. if (parent) {
  701. if (node == parent->left) {
  702. parent->left = child;
  703. left_deleted = true;
  704. } else {
  705. parent->right = child;
  706. left_deleted = false;
  707. }
  708. if (child) {
  709. avl_set_parent(child, parent);
  710. }
  711. } else {
  712. if (child) {
  713. avl_set_parent(child, parent);
  714. }
  715. *root_ptr = child;
  716. return;
  717. }
  718. }
  719. /* Rebalance the tree. */
  720. do {
  721. if (left_deleted) {
  722. parent = avl_handle_subtree_shrink(root_ptr, parent, +1, &left_deleted);
  723. } else {
  724. parent = avl_handle_subtree_shrink(root_ptr, parent, -1, &left_deleted);
  725. }
  726. } while (parent);
  727. }