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.

406 lines
13 KiB

  1. /* avl.c (binary search tree) */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  6. * 2009, 2010, 2011, 2013 Andrew Makhorin, Department for Applied
  7. * Informatics, Moscow Aviation Institute, Moscow, Russia. All rights
  8. * reserved. E-mail: <mao@gnu.org>.
  9. *
  10. * GLPK is free software: you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  18. * License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************/
  23. #include "avl.h"
  24. #include "dmp.h"
  25. #include "env.h"
  26. struct AVL
  27. { /* AVL tree (Adelson-Velsky & Landis binary search tree) */
  28. DMP *pool;
  29. /* memory pool for allocating nodes */
  30. AVLNODE *root;
  31. /* pointer to the root node */
  32. int (*fcmp)(void *info, const void *key1, const void *key2);
  33. /* application-defined key comparison routine */
  34. void *info;
  35. /* transit pointer passed to the routine fcmp */
  36. int size;
  37. /* the tree size (the total number of nodes) */
  38. int height;
  39. /* the tree height */
  40. };
  41. struct AVLNODE
  42. { /* node of AVL tree */
  43. const void *key;
  44. /* pointer to the node key (data structure for representing keys
  45. is supplied by the application) */
  46. int rank;
  47. /* node rank = relative position of the node in its own subtree =
  48. the number of nodes in the left subtree plus one */
  49. int type;
  50. /* reserved for the application specific information */
  51. void *link;
  52. /* reserved for the application specific information */
  53. AVLNODE *up;
  54. /* pointer to the parent node */
  55. short int flag;
  56. /* node flag:
  57. 0 - this node is the left child of its parent (or this node is
  58. the root of the tree and has no parent)
  59. 1 - this node is the right child of its parent */
  60. short int bal;
  61. /* node balance = the difference between heights of the right and
  62. left subtrees:
  63. -1 - the left subtree is higher than the right one;
  64. 0 - the left and right subtrees have the same height;
  65. +1 - the left subtree is lower than the right one */
  66. AVLNODE *left;
  67. /* pointer to the root of the left subtree */
  68. AVLNODE *right;
  69. /* pointer to the root of the right subtree */
  70. };
  71. AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1,
  72. const void *key2), void *info)
  73. { /* create AVL tree */
  74. AVL *tree;
  75. tree = xmalloc(sizeof(AVL));
  76. tree->pool = dmp_create_pool();
  77. tree->root = NULL;
  78. tree->fcmp = fcmp;
  79. tree->info = info;
  80. tree->size = 0;
  81. tree->height = 0;
  82. return tree;
  83. }
  84. int avl_strcmp(void *info, const void *key1, const void *key2)
  85. { /* compare character string keys */
  86. xassert(info == info);
  87. return strcmp(key1, key2);
  88. }
  89. static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node);
  90. AVLNODE *avl_insert_node(AVL *tree, const void *key)
  91. { /* insert new node into AVL tree */
  92. AVLNODE *p, *q, *r;
  93. short int flag;
  94. /* find an appropriate point for insertion */
  95. p = NULL; q = tree->root;
  96. while (q != NULL)
  97. { p = q;
  98. if (tree->fcmp(tree->info, key, p->key) <= 0)
  99. { flag = 0;
  100. q = p->left;
  101. p->rank++;
  102. }
  103. else
  104. { flag = 1;
  105. q = p->right;
  106. }
  107. }
  108. /* create new node and insert it into the tree */
  109. r = dmp_get_atom(tree->pool, sizeof(AVLNODE));
  110. r->key = key; r->type = 0; r->link = NULL;
  111. r->rank = 1; r->up = p;
  112. r->flag = (short int)(p == NULL ? 0 : flag);
  113. r->bal = 0; r->left = NULL; r->right = NULL;
  114. tree->size++;
  115. if (p == NULL)
  116. tree->root = r;
  117. else
  118. if (flag == 0) p->left = r; else p->right = r;
  119. /* go upstairs to the root and correct all subtrees affected by
  120. insertion */
  121. while (p != NULL)
  122. { if (flag == 0)
  123. { /* the height of the left subtree of [p] is increased */
  124. if (p->bal > 0)
  125. { p->bal = 0;
  126. break;
  127. }
  128. if (p->bal < 0)
  129. { rotate_subtree(tree, p);
  130. break;
  131. }
  132. p->bal = -1; flag = p->flag; p = p->up;
  133. }
  134. else
  135. { /* the height of the right subtree of [p] is increased */
  136. if (p->bal < 0)
  137. { p->bal = 0;
  138. break;
  139. }
  140. if (p->bal > 0)
  141. { rotate_subtree(tree, p);
  142. break;
  143. }
  144. p->bal = +1; flag = p->flag; p = p->up;
  145. }
  146. }
  147. /* if the root has been reached, the height of the entire tree is
  148. increased */
  149. if (p == NULL) tree->height++;
  150. return r;
  151. }
  152. void avl_set_node_type(AVLNODE *node, int type)
  153. { /* assign the type field of specified node */
  154. node->type = type;
  155. return;
  156. }
  157. void avl_set_node_link(AVLNODE *node, void *link)
  158. { /* assign the link field of specified node */
  159. node->link = link;
  160. return;
  161. }
  162. AVLNODE *avl_find_node(AVL *tree, const void *key)
  163. { /* find node in AVL tree */
  164. AVLNODE *p;
  165. int c;
  166. p = tree->root;
  167. while (p != NULL)
  168. { c = tree->fcmp(tree->info, key, p->key);
  169. if (c == 0) break;
  170. p = (c < 0 ? p->left : p->right);
  171. }
  172. return p;
  173. }
  174. int avl_get_node_type(AVLNODE *node)
  175. { /* retrieve the type field of specified node */
  176. return node->type;
  177. }
  178. void *avl_get_node_link(AVLNODE *node)
  179. { /* retrieve the link field of specified node */
  180. return node->link;
  181. }
  182. static AVLNODE *find_next_node(AVL *tree, AVLNODE *node)
  183. { /* find next node in AVL tree */
  184. AVLNODE *p, *q;
  185. if (tree->root == NULL) return NULL;
  186. p = node;
  187. q = (p == NULL ? tree->root : p->right);
  188. if (q == NULL)
  189. { /* go upstairs from the left subtree */
  190. for (;;)
  191. { q = p->up;
  192. if (q == NULL) break;
  193. if (p->flag == 0) break;
  194. p = q;
  195. }
  196. }
  197. else
  198. { /* go downstairs into the right subtree */
  199. for (;;)
  200. { p = q->left;
  201. if (p == NULL) break;
  202. q = p;
  203. }
  204. }
  205. return q;
  206. }
  207. void avl_delete_node(AVL *tree, AVLNODE *node)
  208. { /* delete specified node from AVL tree */
  209. AVLNODE *f, *p, *q, *r, *s, *x, *y;
  210. short int flag;
  211. p = node;
  212. /* if both subtrees of the specified node are non-empty, the node
  213. should be interchanged with the next one, at least one subtree
  214. of which is always empty */
  215. if (p->left == NULL || p->right == NULL) goto skip;
  216. f = p->up; q = p->left;
  217. r = find_next_node(tree, p); s = r->right;
  218. if (p->right == r)
  219. { if (f == NULL)
  220. tree->root = r;
  221. else
  222. if (p->flag == 0) f->left = r; else f->right = r;
  223. r->rank = p->rank; r->up = f;
  224. r->flag = p->flag; r->bal = p->bal;
  225. r->left = q; r->right = p;
  226. q->up = r;
  227. p->rank = 1; p->up = r; p->flag = 1;
  228. p->bal = (short int)(s == NULL ? 0 : +1);
  229. p->left = NULL; p->right = s;
  230. if (s != NULL) s->up = p;
  231. }
  232. else
  233. { x = p->right; y = r->up;
  234. if (f == NULL)
  235. tree->root = r;
  236. else
  237. if (p->flag == 0) f->left = r; else f->right = r;
  238. r->rank = p->rank; r->up = f;
  239. r->flag = p->flag; r->bal = p->bal;
  240. r->left = q; r->right = x;
  241. q->up = r; x->up = r; y->left = p;
  242. p->rank = 1; p->up = y; p->flag = 0;
  243. p->bal = (short int)(s == NULL ? 0 : +1);
  244. p->left = NULL; p->right = s;
  245. if (s != NULL) s->up = p;
  246. }
  247. skip: /* now the specified node [p] has at least one empty subtree;
  248. go upstairs to the root and adjust the rank field of all nodes
  249. affected by deletion */
  250. q = p; f = q->up;
  251. while (f != NULL)
  252. { if (q->flag == 0) f->rank--;
  253. q = f; f = q->up;
  254. }
  255. /* delete the specified node from the tree */
  256. f = p->up; flag = p->flag;
  257. q = p->left != NULL ? p->left : p->right;
  258. if (f == NULL)
  259. tree->root = q;
  260. else
  261. if (flag == 0) f->left = q; else f->right = q;
  262. if (q != NULL) q->up = f, q->flag = flag;
  263. tree->size--;
  264. /* go upstairs to the root and correct all subtrees affected by
  265. deletion */
  266. while (f != NULL)
  267. { if (flag == 0)
  268. { /* the height of the left subtree of [f] is decreased */
  269. if (f->bal == 0)
  270. { f->bal = +1;
  271. break;
  272. }
  273. if (f->bal < 0)
  274. f->bal = 0;
  275. else
  276. { f = rotate_subtree(tree, f);
  277. if (f->bal < 0) break;
  278. }
  279. flag = f->flag; f = f->up;
  280. }
  281. else
  282. { /* the height of the right subtree of [f] is decreased */
  283. if (f->bal == 0)
  284. { f->bal = -1;
  285. break;
  286. }
  287. if (f->bal > 0)
  288. f->bal = 0;
  289. else
  290. { f = rotate_subtree(tree, f);
  291. if (f->bal > 0) break;
  292. }
  293. flag = f->flag; f = f->up;
  294. }
  295. }
  296. /* if the root has been reached, the height of the entire tree is
  297. decreased */
  298. if (f == NULL) tree->height--;
  299. /* returns the deleted node to the memory pool */
  300. dmp_free_atom(tree->pool, p, sizeof(AVLNODE));
  301. return;
  302. }
  303. static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node)
  304. { /* restore balance of AVL subtree */
  305. AVLNODE *f, *p, *q, *r, *x, *y;
  306. xassert(node != NULL);
  307. p = node;
  308. if (p->bal < 0)
  309. { /* perform negative (left) rotation */
  310. f = p->up; q = p->left; r = q->right;
  311. if (q->bal <= 0)
  312. { /* perform single negative rotation */
  313. if (f == NULL)
  314. tree->root = q;
  315. else
  316. if (p->flag == 0) f->left = q; else f->right = q;
  317. p->rank -= q->rank;
  318. q->up = f; q->flag = p->flag; q->bal++; q->right = p;
  319. p->up = q; p->flag = 1;
  320. p->bal = (short int)(-q->bal); p->left = r;
  321. if (r != NULL) r->up = p, r->flag = 0;
  322. node = q;
  323. }
  324. else
  325. { /* perform double negative rotation */
  326. x = r->left; y = r->right;
  327. if (f == NULL)
  328. tree->root = r;
  329. else
  330. if (p->flag == 0) f->left = r; else f->right = r;
  331. p->rank -= (q->rank + r->rank);
  332. r->rank += q->rank;
  333. p->bal = (short int)(r->bal >= 0 ? 0 : +1);
  334. q->bal = (short int)(r->bal <= 0 ? 0 : -1);
  335. r->up = f; r->flag = p->flag; r->bal = 0;
  336. r->left = q; r->right = p;
  337. p->up = r; p->flag = 1; p->left = y;
  338. q->up = r; q->flag = 0; q->right = x;
  339. if (x != NULL) x->up = q, x->flag = 1;
  340. if (y != NULL) y->up = p, y->flag = 0;
  341. node = r;
  342. }
  343. }
  344. else
  345. { /* perform positive (right) rotation */
  346. f = p->up; q = p->right; r = q->left;
  347. if (q->bal >= 0)
  348. { /* perform single positive rotation */
  349. if (f == NULL)
  350. tree->root = q;
  351. else
  352. if (p->flag == 0) f->left = q; else f->right = q;
  353. q->rank += p->rank;
  354. q->up = f; q->flag = p->flag; q->bal--; q->left = p;
  355. p->up = q; p->flag = 0;
  356. p->bal = (short int)(-q->bal); p->right = r;
  357. if (r != NULL) r->up = p, r->flag = 1;
  358. node = q;
  359. }
  360. else
  361. { /* perform double positive rotation */
  362. x = r->left; y = r->right;
  363. if (f == NULL)
  364. tree->root = r;
  365. else
  366. if (p->flag == 0) f->left = r; else f->right = r;
  367. q->rank -= r->rank;
  368. r->rank += p->rank;
  369. p->bal = (short int)(r->bal <= 0 ? 0 : -1);
  370. q->bal = (short int)(r->bal >= 0 ? 0 : +1);
  371. r->up = f; r->flag = p->flag; r->bal = 0;
  372. r->left = p; r->right = q;
  373. p->up = r; p->flag = 0; p->right = x;
  374. q->up = r; q->flag = 1; q->left = y;
  375. if (x != NULL) x->up = p, x->flag = 1;
  376. if (y != NULL) y->up = q, y->flag = 0;
  377. node = r;
  378. }
  379. }
  380. return node;
  381. }
  382. void avl_delete_tree(AVL *tree)
  383. { /* delete AVL tree */
  384. dmp_delete_pool(tree->pool);
  385. xfree(tree);
  386. return;
  387. }
  388. /* eof */