gl_rbtree_ordered.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /* Ordered {set,map} data type implemented by a binary tree.
  2. Copyright (C) 2006-2007, 2009-2020 Free Software Foundation, Inc.
  3. Written by Bruno Haible <bruno@clisp.org>, 2006.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  14. /* A red-black tree is a binary tree where every node is colored black or
  15. red such that
  16. 1. The root is black.
  17. 2. No red node has a red parent.
  18. Or equivalently: No red node has a red child.
  19. 3. All paths from the root down to any NULL endpoint contain the same
  20. number of black nodes.
  21. Let's call this the "black-height" bh of the tree. It follows that every
  22. such path contains exactly bh black and between 0 and bh red nodes. (The
  23. extreme cases are a path containing only black nodes, and a path colored
  24. alternately black-red-black-red-...-black-red.) The height of the tree
  25. therefore is >= bh, <= 2*bh.
  26. */
  27. /* Color of a node. */
  28. typedef enum color { BLACK, RED } color_t;
  29. /* Tree node implementation, valid for this file only. */
  30. struct NODE_IMPL
  31. {
  32. struct NODE_IMPL *left; /* left branch, or NULL */
  33. struct NODE_IMPL *right; /* right branch, or NULL */
  34. /* Parent pointer, or NULL. The parent pointer is not needed for most
  35. operations. It is needed so that a NODE_T can be returned without
  36. memory allocation, on which the functions <container>_remove_node,
  37. <container>_add_before, <container>_add_after can be implemented. */
  38. struct NODE_IMPL *parent;
  39. color_t color; /* node's color */
  40. NODE_PAYLOAD_FIELDS
  41. };
  42. typedef struct NODE_IMPL * NODE_T;
  43. /* Concrete CONTAINER_IMPL type, valid for this file only. */
  44. struct CONTAINER_IMPL
  45. {
  46. struct CONTAINER_IMPL_BASE base;
  47. struct NODE_IMPL *root; /* root node or NULL */
  48. size_t count; /* number of nodes */
  49. };
  50. /* A red-black tree of height h has a black-height bh >= ceil(h/2) and
  51. therefore at least 2^ceil(h/2) - 1 elements. So, h <= 116 (because a tree
  52. of height h >= 117 would have at least 2^59 - 1 elements, and because even
  53. on 64-bit machines,
  54. sizeof (NODE_IMPL) * (2^59 - 1) > 2^64
  55. this would exceed the address space of the machine. */
  56. #define MAXHEIGHT 116
  57. /* Rotates left a subtree.
  58. B D
  59. / \ / \
  60. A D --> B E
  61. / \ / \
  62. C E A C
  63. Changes the tree structure, updates the branch sizes.
  64. The caller must update the colors and register D as child of its parent. */
  65. static NODE_T
  66. rotate_left (NODE_T b_node, NODE_T d_node)
  67. {
  68. NODE_T c_node = d_node->left;
  69. b_node->right = c_node;
  70. d_node->left = b_node;
  71. d_node->parent = b_node->parent;
  72. b_node->parent = d_node;
  73. if (c_node != NULL)
  74. c_node->parent = b_node;
  75. return d_node;
  76. }
  77. /* Rotates right a subtree.
  78. D B
  79. / \ / \
  80. B E --> A D
  81. / \ / \
  82. A C C E
  83. Changes the tree structure, updates the branch sizes.
  84. The caller must update the colors and register B as child of its parent. */
  85. static NODE_T
  86. rotate_right (NODE_T b_node, NODE_T d_node)
  87. {
  88. NODE_T c_node = b_node->right;
  89. d_node->left = c_node;
  90. b_node->right = d_node;
  91. b_node->parent = d_node->parent;
  92. d_node->parent = b_node;
  93. if (c_node != NULL)
  94. c_node->parent = d_node;
  95. return b_node;
  96. }
  97. /* Ensures the tree is balanced, after an insertion operation.
  98. Also assigns node->color.
  99. parent is the given node's parent, known to be non-NULL. */
  100. static void
  101. rebalance_after_add (CONTAINER_T container, NODE_T node, NODE_T parent)
  102. {
  103. for (;;)
  104. {
  105. /* At this point, parent = node->parent != NULL.
  106. Think of node->color being RED (although node->color is not yet
  107. assigned.) */
  108. NODE_T grandparent;
  109. NODE_T uncle;
  110. if (parent->color == BLACK)
  111. {
  112. /* A RED color for node is acceptable. */
  113. node->color = RED;
  114. return;
  115. }
  116. grandparent = parent->parent;
  117. /* Since parent is RED, we know that
  118. grandparent is != NULL and colored BLACK. */
  119. if (grandparent->left == parent)
  120. uncle = grandparent->right;
  121. else if (grandparent->right == parent)
  122. uncle = grandparent->left;
  123. else
  124. abort ();
  125. if (uncle != NULL && uncle->color == RED)
  126. {
  127. /* Change grandparent from BLACK to RED, and
  128. change parent and uncle from RED to BLACK.
  129. This makes it acceptable for node to be RED. */
  130. node->color = RED;
  131. parent->color = uncle->color = BLACK;
  132. node = grandparent;
  133. }
  134. else
  135. {
  136. /* grandparent and uncle are BLACK. parent is RED. node wants
  137. to be RED too.
  138. In this case, recoloring is not sufficient. Need to perform
  139. one or two rotations. */
  140. NODE_T *grandparentp;
  141. if (grandparent->parent == NULL)
  142. grandparentp = &container->root;
  143. else if (grandparent->parent->left == grandparent)
  144. grandparentp = &grandparent->parent->left;
  145. else if (grandparent->parent->right == grandparent)
  146. grandparentp = &grandparent->parent->right;
  147. else
  148. abort ();
  149. if (grandparent->left == parent)
  150. {
  151. if (parent->right == node)
  152. {
  153. /* Rotation between node and parent. */
  154. grandparent->left = rotate_left (parent, node);
  155. node = parent;
  156. parent = grandparent->left;
  157. }
  158. /* grandparent and uncle are BLACK. parent and node want to be
  159. RED. parent = grandparent->left. node = parent->left.
  160. grandparent parent
  161. bh+1 bh+1
  162. / \ / \
  163. parent uncle --> node grandparent
  164. bh bh bh bh
  165. / \ / \
  166. node C C uncle
  167. bh bh bh bh
  168. */
  169. *grandparentp = rotate_right (parent, grandparent);
  170. parent->color = BLACK;
  171. node->color = grandparent->color = RED;
  172. }
  173. else /* grandparent->right == parent */
  174. {
  175. if (parent->left == node)
  176. {
  177. /* Rotation between node and parent. */
  178. grandparent->right = rotate_right (node, parent);
  179. node = parent;
  180. parent = grandparent->right;
  181. }
  182. /* grandparent and uncle are BLACK. parent and node want to be
  183. RED. parent = grandparent->right. node = parent->right.
  184. grandparent parent
  185. bh+1 bh+1
  186. / \ / \
  187. uncle parent --> grandparent node
  188. bh bh bh bh
  189. / \ / \
  190. C node uncle C
  191. bh bh bh bh
  192. */
  193. *grandparentp = rotate_left (grandparent, parent);
  194. parent->color = BLACK;
  195. node->color = grandparent->color = RED;
  196. }
  197. return;
  198. }
  199. /* Start again with a new (node, parent) pair. */
  200. parent = node->parent;
  201. if (parent == NULL)
  202. {
  203. /* Change node's color from RED to BLACK. This increases the
  204. tree's black-height. */
  205. node->color = BLACK;
  206. return;
  207. }
  208. }
  209. }
  210. /* Ensures the tree is balanced, after a deletion operation.
  211. CHILD was a grandchild of PARENT and is now its child. Between them,
  212. a black node was removed. CHILD is also black, or NULL.
  213. (CHILD can also be NULL. But PARENT is non-NULL.) */
  214. static void
  215. rebalance_after_remove (CONTAINER_T container, NODE_T child, NODE_T parent)
  216. {
  217. for (;;)
  218. {
  219. /* At this point, we reduced the black-height of the CHILD subtree by 1.
  220. To make up, either look for a possibility to turn a RED to a BLACK
  221. node, or try to reduce the black-height tree of CHILD's sibling
  222. subtree as well. */
  223. NODE_T *parentp;
  224. if (parent->parent == NULL)
  225. parentp = &container->root;
  226. else if (parent->parent->left == parent)
  227. parentp = &parent->parent->left;
  228. else if (parent->parent->right == parent)
  229. parentp = &parent->parent->right;
  230. else
  231. abort ();
  232. if (parent->left == child)
  233. {
  234. NODE_T sibling = parent->right;
  235. /* sibling's black-height is >= 1. In particular,
  236. sibling != NULL.
  237. parent
  238. / \
  239. child sibling
  240. bh bh+1
  241. */
  242. if (sibling->color == RED)
  243. {
  244. /* sibling is RED, hence parent is BLACK and sibling's children
  245. are non-NULL and BLACK.
  246. parent sibling
  247. bh+2 bh+2
  248. / \ / \
  249. child sibling --> parent SR
  250. bh bh+1 bh+1 bh+1
  251. / \ / \
  252. SL SR child SL
  253. bh+1 bh+1 bh bh+1
  254. */
  255. *parentp = rotate_left (parent, sibling);
  256. parent->color = RED;
  257. sibling->color = BLACK;
  258. /* Concentrate on the subtree of parent. The new sibling is
  259. one of the old sibling's children, and known to be BLACK. */
  260. parentp = &sibling->left;
  261. sibling = parent->right;
  262. }
  263. /* Now we know that sibling is BLACK.
  264. parent
  265. / \
  266. child sibling
  267. bh bh+1
  268. */
  269. if (sibling->right != NULL && sibling->right->color == RED)
  270. {
  271. /*
  272. parent sibling
  273. bh+1|bh+2 bh+1|bh+2
  274. / \ / \
  275. child sibling --> parent SR
  276. bh bh+1 bh+1 bh+1
  277. / \ / \
  278. SL SR child SL
  279. bh bh bh bh
  280. */
  281. *parentp = rotate_left (parent, sibling);
  282. sibling->color = parent->color;
  283. parent->color = BLACK;
  284. sibling->right->color = BLACK;
  285. return;
  286. }
  287. else if (sibling->left != NULL && sibling->left->color == RED)
  288. {
  289. /*
  290. parent parent
  291. bh+1|bh+2 bh+1|bh+2
  292. / \ / \
  293. child sibling --> child SL
  294. bh bh+1 bh bh+1
  295. / \ / \
  296. SL SR SLL sibling
  297. bh bh bh bh
  298. / \ / \
  299. SLL SLR SLR SR
  300. bh bh bh bh
  301. where SLL, SLR, SR are all black.
  302. */
  303. parent->right = rotate_right (sibling->left, sibling);
  304. /* Change sibling from BLACK to RED and SL from RED to BLACK. */
  305. sibling->color = RED;
  306. sibling = parent->right;
  307. sibling->color = BLACK;
  308. /* Now do as in the previous case. */
  309. *parentp = rotate_left (parent, sibling);
  310. sibling->color = parent->color;
  311. parent->color = BLACK;
  312. sibling->right->color = BLACK;
  313. return;
  314. }
  315. else
  316. {
  317. if (parent->color == BLACK)
  318. {
  319. /* Change sibling from BLACK to RED. Then the entire
  320. subtree at parent has decreased its black-height.
  321. parent parent
  322. bh+2 bh+1
  323. / \ / \
  324. child sibling --> child sibling
  325. bh bh+1 bh bh
  326. */
  327. sibling->color = RED;
  328. child = parent;
  329. }
  330. else
  331. {
  332. /* Change parent from RED to BLACK, but compensate by
  333. changing sibling from BLACK to RED.
  334. parent parent
  335. bh+1 bh+1
  336. / \ / \
  337. child sibling --> child sibling
  338. bh bh+1 bh bh
  339. */
  340. parent->color = BLACK;
  341. sibling->color = RED;
  342. return;
  343. }
  344. }
  345. }
  346. else if (parent->right == child)
  347. {
  348. NODE_T sibling = parent->left;
  349. /* sibling's black-height is >= 1. In particular,
  350. sibling != NULL.
  351. parent
  352. / \
  353. sibling child
  354. bh+1 bh
  355. */
  356. if (sibling->color == RED)
  357. {
  358. /* sibling is RED, hence parent is BLACK and sibling's children
  359. are non-NULL and BLACK.
  360. parent sibling
  361. bh+2 bh+2
  362. / \ / \
  363. sibling child --> SR parent
  364. bh+1 ch bh+1 bh+1
  365. / \ / \
  366. SL SR SL child
  367. bh+1 bh+1 bh+1 bh
  368. */
  369. *parentp = rotate_right (sibling, parent);
  370. parent->color = RED;
  371. sibling->color = BLACK;
  372. /* Concentrate on the subtree of parent. The new sibling is
  373. one of the old sibling's children, and known to be BLACK. */
  374. parentp = &sibling->right;
  375. sibling = parent->left;
  376. }
  377. /* Now we know that sibling is BLACK.
  378. parent
  379. / \
  380. sibling child
  381. bh+1 bh
  382. */
  383. if (sibling->left != NULL && sibling->left->color == RED)
  384. {
  385. /*
  386. parent sibling
  387. bh+1|bh+2 bh+1|bh+2
  388. / \ / \
  389. sibling child --> SL parent
  390. bh+1 bh bh+1 bh+1
  391. / \ / \
  392. SL SR SR child
  393. bh bh bh bh
  394. */
  395. *parentp = rotate_right (sibling, parent);
  396. sibling->color = parent->color;
  397. parent->color = BLACK;
  398. sibling->left->color = BLACK;
  399. return;
  400. }
  401. else if (sibling->right != NULL && sibling->right->color == RED)
  402. {
  403. /*
  404. parent parent
  405. bh+1|bh+2 bh+1|bh+2
  406. / \ / \
  407. sibling child --> SR child
  408. bh+1 bh bh+1 bh
  409. / \ / \
  410. SL SR sibling SRR
  411. bh bh bh bh
  412. / \ / \
  413. SRL SRR SL SRL
  414. bh bh bh bh
  415. where SL, SRL, SRR are all black.
  416. */
  417. parent->left = rotate_left (sibling, sibling->right);
  418. /* Change sibling from BLACK to RED and SL from RED to BLACK. */
  419. sibling->color = RED;
  420. sibling = parent->left;
  421. sibling->color = BLACK;
  422. /* Now do as in the previous case. */
  423. *parentp = rotate_right (sibling, parent);
  424. sibling->color = parent->color;
  425. parent->color = BLACK;
  426. sibling->left->color = BLACK;
  427. return;
  428. }
  429. else
  430. {
  431. if (parent->color == BLACK)
  432. {
  433. /* Change sibling from BLACK to RED. Then the entire
  434. subtree at parent has decreased its black-height.
  435. parent parent
  436. bh+2 bh+1
  437. / \ / \
  438. sibling child --> sibling child
  439. bh+1 bh bh bh
  440. */
  441. sibling->color = RED;
  442. child = parent;
  443. }
  444. else
  445. {
  446. /* Change parent from RED to BLACK, but compensate by
  447. changing sibling from BLACK to RED.
  448. parent parent
  449. bh+1 bh+1
  450. / \ / \
  451. sibling child --> sibling child
  452. bh+1 bh bh bh
  453. */
  454. parent->color = BLACK;
  455. sibling->color = RED;
  456. return;
  457. }
  458. }
  459. }
  460. else
  461. abort ();
  462. /* Start again with a new (child, parent) pair. */
  463. parent = child->parent;
  464. #if 0 /* Already handled. */
  465. if (child != NULL && child->color == RED)
  466. {
  467. child->color = BLACK;
  468. return;
  469. }
  470. #endif
  471. if (parent == NULL)
  472. return;
  473. }
  474. }
  475. static NODE_T
  476. gl_tree_nx_add_first (CONTAINER_T container, NODE_PAYLOAD_PARAMS)
  477. {
  478. /* Create new node. */
  479. NODE_T new_node =
  480. (struct NODE_IMPL *) malloc (sizeof (struct NODE_IMPL));
  481. if (new_node == NULL)
  482. return NULL;
  483. new_node->left = NULL;
  484. new_node->right = NULL;
  485. NODE_PAYLOAD_ASSIGN(new_node)
  486. /* Add it to the tree. */
  487. if (container->root == NULL)
  488. {
  489. new_node->color = BLACK;
  490. container->root = new_node;
  491. new_node->parent = NULL;
  492. }
  493. else
  494. {
  495. NODE_T node;
  496. for (node = container->root; node->left != NULL; )
  497. node = node->left;
  498. node->left = new_node;
  499. new_node->parent = node;
  500. /* Color and rebalance. */
  501. rebalance_after_add (container, new_node, node);
  502. }
  503. container->count++;
  504. return new_node;
  505. }
  506. /* Adds the already allocated NEW_NODE to the tree, right before NODE. */
  507. static void
  508. gl_tree_add_node_before (CONTAINER_T container, NODE_T node, NODE_T new_node)
  509. {
  510. new_node->left = NULL;
  511. new_node->right = NULL;
  512. /* Add it to the tree. */
  513. if (node->left == NULL)
  514. node->left = new_node;
  515. else
  516. {
  517. for (node = node->left; node->right != NULL; )
  518. node = node->right;
  519. node->right = new_node;
  520. }
  521. new_node->parent = node;
  522. /* Color and rebalance. */
  523. rebalance_after_add (container, new_node, node);
  524. container->count++;
  525. }
  526. static NODE_T
  527. gl_tree_nx_add_before (CONTAINER_T container, NODE_T node, NODE_PAYLOAD_PARAMS)
  528. {
  529. /* Create new node. */
  530. NODE_T new_node =
  531. (struct NODE_IMPL *) malloc (sizeof (struct NODE_IMPL));
  532. if (new_node == NULL)
  533. return NULL;
  534. NODE_PAYLOAD_ASSIGN(new_node)
  535. gl_tree_add_node_before (container, node, new_node);
  536. return new_node;
  537. }
  538. /* Adds the already allocated NEW_NODE to the tree, right after NODE. */
  539. static void
  540. gl_tree_add_node_after (CONTAINER_T container, NODE_T node, NODE_T new_node)
  541. {
  542. new_node->left = NULL;
  543. new_node->right = NULL;
  544. /* Add it to the tree. */
  545. if (node->right == NULL)
  546. node->right = new_node;
  547. else
  548. {
  549. for (node = node->right; node->left != NULL; )
  550. node = node->left;
  551. node->left = new_node;
  552. }
  553. new_node->parent = node;
  554. /* Color and rebalance. */
  555. rebalance_after_add (container, new_node, node);
  556. container->count++;
  557. }
  558. static NODE_T
  559. gl_tree_nx_add_after (CONTAINER_T container, NODE_T node, NODE_PAYLOAD_PARAMS)
  560. {
  561. /* Create new node. */
  562. NODE_T new_node =
  563. (struct NODE_IMPL *) malloc (sizeof (struct NODE_IMPL));
  564. if (new_node == NULL)
  565. return NULL;
  566. NODE_PAYLOAD_ASSIGN(new_node)
  567. gl_tree_add_node_after (container, node, new_node);
  568. return new_node;
  569. }
  570. static void
  571. gl_tree_remove_node_no_free (CONTAINER_T container, NODE_T node)
  572. {
  573. NODE_T parent = node->parent;
  574. if (node->left == NULL)
  575. {
  576. /* Replace node with node->right. */
  577. NODE_T child = node->right;
  578. if (child != NULL)
  579. {
  580. child->parent = parent;
  581. /* Since node->left == NULL, child must be RED and of height 1,
  582. hence node must have been BLACK. Recolor the child. */
  583. child->color = BLACK;
  584. }
  585. if (parent == NULL)
  586. container->root = child;
  587. else
  588. {
  589. if (parent->left == node)
  590. parent->left = child;
  591. else /* parent->right == node */
  592. parent->right = child;
  593. if (child == NULL && node->color == BLACK)
  594. rebalance_after_remove (container, child, parent);
  595. }
  596. }
  597. else if (node->right == NULL)
  598. {
  599. /* It is not absolutely necessary to treat this case. But the more
  600. general case below is more complicated, hence slower. */
  601. /* Replace node with node->left. */
  602. NODE_T child = node->left;
  603. child->parent = parent;
  604. /* Since node->right == NULL, child must be RED and of height 1,
  605. hence node must have been BLACK. Recolor the child. */
  606. child->color = BLACK;
  607. if (parent == NULL)
  608. container->root = child;
  609. else
  610. {
  611. if (parent->left == node)
  612. parent->left = child;
  613. else /* parent->right == node */
  614. parent->right = child;
  615. }
  616. }
  617. else
  618. {
  619. /* Replace node with the rightmost element of the node->left subtree. */
  620. NODE_T subst;
  621. NODE_T subst_parent;
  622. NODE_T child;
  623. color_t removed_color;
  624. for (subst = node->left; subst->right != NULL; )
  625. subst = subst->right;
  626. subst_parent = subst->parent;
  627. child = subst->left;
  628. removed_color = subst->color;
  629. /* The case subst_parent == node is special: If we do nothing special,
  630. we get confusion about node->left, subst->left and child->parent.
  631. subst_parent == node
  632. <==> The 'for' loop above terminated immediately.
  633. <==> subst == subst_parent->left
  634. [otherwise subst == subst_parent->right]
  635. In this case, we would need to first set
  636. child->parent = node; node->left = child;
  637. and later - when we copy subst into node's position - again
  638. child->parent = subst; subst->left = child;
  639. Altogether a no-op. */
  640. if (subst_parent != node)
  641. {
  642. if (child != NULL)
  643. child->parent = subst_parent;
  644. subst_parent->right = child;
  645. }
  646. /* Copy subst into node's position.
  647. (This is safer than to copy subst's value into node, keep node in
  648. place, and free subst.) */
  649. if (subst_parent != node)
  650. {
  651. subst->left = node->left;
  652. subst->left->parent = subst;
  653. }
  654. subst->right = node->right;
  655. subst->right->parent = subst;
  656. subst->color = node->color;
  657. subst->parent = parent;
  658. if (parent == NULL)
  659. container->root = subst;
  660. else if (parent->left == node)
  661. parent->left = subst;
  662. else /* parent->right == node */
  663. parent->right = subst;
  664. if (removed_color == BLACK)
  665. {
  666. if (child != NULL && child->color == RED)
  667. /* Recolor the child. */
  668. child->color = BLACK;
  669. else
  670. /* Rebalancing starts at child's parent, that is subst_parent -
  671. except when subst_parent == node. In this case, we need to use
  672. its replacement, subst. */
  673. rebalance_after_remove (container, child,
  674. subst_parent != node ? subst_parent : subst);
  675. }
  676. }
  677. container->count--;
  678. }
  679. static bool
  680. gl_tree_remove_node (CONTAINER_T container, NODE_T node)
  681. {
  682. gl_tree_remove_node_no_free (container, node);
  683. NODE_PAYLOAD_DISPOSE (container, node)
  684. free (node);
  685. return true;
  686. }
  687. /* For debugging. */
  688. static unsigned int
  689. check_invariants (NODE_T node, NODE_T parent, size_t *counterp)
  690. {
  691. unsigned int left_blackheight =
  692. (node->left != NULL ? check_invariants (node->left, node, counterp) : 0);
  693. unsigned int right_blackheight =
  694. (node->right != NULL ? check_invariants (node->right, node, counterp) : 0);
  695. if (!(node->parent == parent))
  696. abort ();
  697. if (!(node->color == BLACK || node->color == RED))
  698. abort ();
  699. if (parent == NULL && !(node->color == BLACK))
  700. abort ();
  701. if (!(left_blackheight == right_blackheight))
  702. abort ();
  703. (*counterp)++;
  704. return left_blackheight + (node->color == BLACK ? 1 : 0);
  705. }