rbbst.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. /****************************************************************************
  2. *
  3. * MODULE: r.viewshed
  4. *
  5. * AUTHOR(S): Laura Toma, Bowdoin College - ltoma@bowdoin.edu
  6. * Yi Zhuang - yzhuang@bowdoin.edu
  7. * Ported to GRASS by William Richard -
  8. * wkrichar@bowdoin.edu or willster3021@gmail.com
  9. * Markus Metz: surface interpolation
  10. *
  11. * Date: april 2011
  12. *
  13. * PURPOSE: To calculate the viewshed (the visible cells in the
  14. * raster) for the given viewpoint (observer) location. The
  15. * visibility model is the following: Two points in the raster are
  16. * considered visible to each other if the cells where they belong are
  17. * visible to each other. Two cells are visible to each other if the
  18. * line-of-sight that connects their centers does not intersect the
  19. * terrain. The terrain is NOT viewed as a tesselation of flat cells,
  20. * i.e. if the line-of-sight does not pass through the cell center,
  21. * elevation is determined using bilinear interpolation.
  22. * The viewshed algorithm is efficient both in
  23. * terms of CPU operations and I/O operations. It has worst-case
  24. * complexity O(n lg n) in the RAM model and O(sort(n)) in the
  25. * I/O-model. For the algorithm and all the other details see the
  26. * paper: "Computing Visibility on * Terrains in External Memory" by
  27. * Herman Haverkort, Laura Toma and Yi Zhuang.
  28. *
  29. * COPYRIGHT: (C) 2008 by the GRASS Development Team
  30. *
  31. * This program is free software under the GNU General Public License
  32. * (>=v2). Read the file COPYING that comes with GRASS for details.
  33. *
  34. *****************************************************************************/
  35. /*
  36. A R/B BST. Always call initNILnode() before using the tree.
  37. Version 0.0.0
  38. Version 0.0.1
  39. Rewrote BST Deletion to improve efficiency
  40. Version 0.0.2
  41. Bug fixed in deletion.
  42. CLRS pseudocode forgot to make sure that x is not NIL before
  43. calling rbDeleteFixup(root,x).
  44. Version 0.0.3
  45. Some Cleanup. Separated the public portion and the
  46. private porthion of the interface in the header
  47. =================================
  48. This is based on BST 1.0.4
  49. BST change log
  50. <---------------->
  51. find max is implemented in this version.
  52. Version 1.0.2
  53. Version 1.0.4
  54. Major bug fix in deletion (when the node has two children,
  55. one of them has a wrong parent pointer after the rotation in the deletion.)
  56. <----------------->
  57. */
  58. #include <stdlib.h>
  59. #include <stdio.h>
  60. #include <assert.h>
  61. #include <math.h>
  62. #include "rbbst.h"
  63. extern "C"
  64. {
  65. #include <grass/gis.h>
  66. #include <grass/glocale.h>
  67. }
  68. TreeNode *NIL;
  69. #define EPSILON 0.0000001
  70. /*public:--------------------------------- */
  71. RBTree *create_tree(TreeValue tv)
  72. {
  73. init_nil_node();
  74. RBTree *rbt = (RBTree *) G_malloc(sizeof(RBTree));
  75. TreeNode *root = (TreeNode *) G_malloc(sizeof(TreeNode));
  76. rbt->root = root;
  77. rbt->root->value = tv;
  78. rbt->root->left = NIL;
  79. rbt->root->right = NIL;
  80. rbt->root->parent = NIL;
  81. rbt->root->color = RB_BLACK;
  82. return rbt;
  83. }
  84. /*LT: not sure if this is correct */
  85. int is_empty(RBTree * t)
  86. {
  87. assert(t);
  88. return (t->root == NIL);
  89. }
  90. void delete_tree(RBTree * t)
  91. {
  92. destroy_sub_tree(t->root);
  93. return;
  94. }
  95. void destroy_sub_tree(TreeNode * node)
  96. {
  97. if (node == NIL)
  98. return;
  99. destroy_sub_tree(node->left);
  100. destroy_sub_tree(node->right);
  101. G_free(node);
  102. return;
  103. }
  104. void insert_into(RBTree * rbt, TreeValue value)
  105. {
  106. insert_into_tree(&(rbt->root), value);
  107. return;
  108. }
  109. void delete_from(RBTree * rbt, double key)
  110. {
  111. delete_from_tree(&(rbt->root), key);
  112. return;
  113. }
  114. TreeNode *search_for_node_with_key(RBTree * rbt, double key)
  115. {
  116. return search_for_node(rbt->root, key);
  117. }
  118. /*------------The following is designed for viewshed's algorithm-------*/
  119. double find_max_gradient_within_key(RBTree * rbt, double key, double angle, double gradient)
  120. {
  121. return find_max_value_within_key(rbt->root, key, angle, gradient);
  122. }
  123. /*<--------------------------------->
  124. //Private below this line */
  125. void init_nil_node()
  126. {
  127. NIL = (TreeNode *) G_malloc(sizeof(TreeNode));
  128. NIL->color = RB_BLACK;
  129. NIL->value.angle[0] = 0;
  130. NIL->value.angle[1] = 0;
  131. NIL->value.angle[2] = 0;
  132. NIL->value.gradient[0] = SMALLEST_GRADIENT;
  133. NIL->value.gradient[1] = SMALLEST_GRADIENT;
  134. NIL->value.gradient[2] = SMALLEST_GRADIENT;
  135. NIL->value.maxGradient = SMALLEST_GRADIENT;
  136. NIL->value.key = 0;
  137. NIL->parent = NULL;
  138. NIL->left = NULL;
  139. NIL->right = NULL;
  140. return;
  141. }
  142. /*you can write change this compare function, depending on your TreeValue struct
  143. //compare function used by findMaxValue
  144. //-1: v1 < v2
  145. //0: v1 = v2
  146. //2: v1 > v2 */
  147. char compare_values(TreeValue * v1, TreeValue * v2)
  148. {
  149. if (v1->gradient[1] > v2->gradient[1])
  150. return 1;
  151. if (v1->gradient[1] < v2->gradient[1])
  152. return -1;
  153. return 0;
  154. }
  155. /*a function used to compare two doubles */
  156. /* a < b : -1
  157. * a > b : 1
  158. * a == b : 0 */
  159. char compare_double(double a, double b)
  160. {
  161. return (a < b ? -1 : (a > b));
  162. }
  163. /*create a tree node */
  164. TreeNode *create_tree_node(TreeValue value)
  165. {
  166. TreeNode *ret;
  167. ret = (TreeNode *) G_malloc(sizeof(TreeNode));
  168. ret->color = RB_RED;
  169. ret->left = NIL;
  170. ret->right = NIL;
  171. ret->parent = NIL;
  172. ret->value = value;
  173. ret->value.maxGradient = SMALLEST_GRADIENT;
  174. return ret;
  175. }
  176. /*create node with its value set to the value given
  177. //and insert the node into the tree
  178. //rbInsertFixup may change the root pointer, so TreeNode** is passed in */
  179. void insert_into_tree(TreeNode ** root, TreeValue value)
  180. {
  181. TreeNode *curNode;
  182. TreeNode *nextNode;
  183. curNode = *root;
  184. if (compare_double(value.key, curNode->value.key) == -1) {
  185. nextNode = curNode->left;
  186. }
  187. else {
  188. nextNode = curNode->right;
  189. }
  190. while (nextNode != NIL) {
  191. curNode = nextNode;
  192. if (compare_double(value.key, curNode->value.key) == -1) {
  193. nextNode = curNode->left;
  194. }
  195. else {
  196. nextNode = curNode->right;
  197. }
  198. }
  199. /*create a new node
  200. //and place it at the right place
  201. //created node is RED by default */
  202. nextNode = create_tree_node(value);
  203. nextNode->parent = curNode;
  204. if (compare_double(value.key, curNode->value.key) == -1) {
  205. curNode->left = nextNode;
  206. }
  207. else {
  208. curNode->right = nextNode;
  209. }
  210. TreeNode *inserted = nextNode;
  211. /*update augmented maxGradient */
  212. nextNode->value.maxGradient = find_value_min_value(&nextNode->value);
  213. while (nextNode->parent != NIL) {
  214. if (nextNode->parent->value.maxGradient < nextNode->value.maxGradient)
  215. nextNode->parent->value.maxGradient = nextNode->value.maxGradient;
  216. if (nextNode->parent->value.maxGradient > nextNode->value.maxGradient)
  217. break;
  218. nextNode = nextNode->parent;
  219. }
  220. /*fix rb tree after insertion */
  221. rb_insert_fixup(root, inserted);
  222. return;
  223. }
  224. void rb_insert_fixup(TreeNode ** root, TreeNode * z)
  225. {
  226. /*see pseudocode on page 281 in CLRS */
  227. TreeNode *y;
  228. while (z->parent->color == RB_RED) {
  229. if (z->parent == z->parent->parent->left) {
  230. y = z->parent->parent->right;
  231. if (y->color == RB_RED) { /*case 1 */
  232. z->parent->color = RB_BLACK;
  233. y->color = RB_BLACK;
  234. z->parent->parent->color = RB_RED;
  235. z = z->parent->parent;
  236. }
  237. else {
  238. if (z == z->parent->right) { /*case 2 */
  239. z = z->parent;
  240. left_rotate(root, z); /*convert case 2 to case 3 */
  241. }
  242. z->parent->color = RB_BLACK; /*case 3 */
  243. z->parent->parent->color = RB_RED;
  244. right_rotate(root, z->parent->parent);
  245. }
  246. }
  247. else { /*(z->parent == z->parent->parent->right) */
  248. y = z->parent->parent->left;
  249. if (y->color == RB_RED) { /*case 1 */
  250. z->parent->color = RB_BLACK;
  251. y->color = RB_BLACK;
  252. z->parent->parent->color = RB_RED;
  253. z = z->parent->parent;
  254. }
  255. else {
  256. if (z == z->parent->left) { /*case 2 */
  257. z = z->parent;
  258. right_rotate(root, z); /*convert case 2 to case 3 */
  259. }
  260. z->parent->color = RB_BLACK; /*case 3 */
  261. z->parent->parent->color = RB_RED;
  262. left_rotate(root, z->parent->parent);
  263. }
  264. }
  265. }
  266. (*root)->color = RB_BLACK;
  267. return;
  268. }
  269. /*search for a node with the given key */
  270. TreeNode *search_for_node(TreeNode * root, double key)
  271. {
  272. TreeNode *curNode = root;
  273. while (curNode != NIL && compare_double(key, curNode->value.key) != 0) {
  274. if (compare_double(key, curNode->value.key) == -1) {
  275. curNode = curNode->left;
  276. }
  277. else {
  278. curNode = curNode->right;
  279. }
  280. }
  281. return curNode;
  282. }
  283. /*function used by treeSuccessor */
  284. TreeNode *tree_minimum(TreeNode * x)
  285. {
  286. while (x->left != NIL)
  287. x = x->left;
  288. return x;
  289. }
  290. /*function used by deletion */
  291. TreeNode *tree_successor(TreeNode * x)
  292. {
  293. if (x->right != NIL)
  294. return tree_minimum(x->right);
  295. TreeNode *y = x->parent;
  296. while (y != NIL && x == y->right) {
  297. x = y;
  298. if (y->parent == NIL)
  299. return y;
  300. y = y->parent;
  301. }
  302. return y;
  303. }
  304. /*delete the node out of the tree */
  305. void delete_from_tree(TreeNode ** root, double key)
  306. {
  307. double tmpMax;
  308. TreeNode *z;
  309. TreeNode *x;
  310. TreeNode *y;
  311. TreeNode *toFix;
  312. z = search_for_node(*root, key);
  313. if (z == NIL) {
  314. /*node to delete is not found */
  315. G_fatal_error(_("Attempt to delete node with key=%f failed"), key);
  316. }
  317. /*1-3 */
  318. if (z->left == NIL || z->right == NIL)
  319. y = z;
  320. else
  321. y = tree_successor(z);
  322. if (y == NIL) {
  323. G_fatal_error(_("Successor node not found. Deletion fails."));
  324. }
  325. /*4-6 */
  326. if (y->left != NIL)
  327. x = y->left;
  328. else
  329. x = y->right;
  330. /*7 */
  331. x->parent = y->parent;
  332. /*8-12 */
  333. if (y->parent == NIL) {
  334. *root = x;
  335. toFix = *root; /*augmentation to be fixed */
  336. }
  337. else {
  338. if (y == y->parent->left)
  339. y->parent->left = x;
  340. else
  341. y->parent->right = x;
  342. toFix = y->parent; /*augmentation to be fixed */
  343. }
  344. /*fix augmentation for removing y */
  345. TreeNode *curNode = y;
  346. double left, right;
  347. while (curNode->parent != NIL) {
  348. if (curNode->parent->value.maxGradient == find_value_min_value(&y->value)) {
  349. left = find_max_value(curNode->parent->left);
  350. right = find_max_value(curNode->parent->right);
  351. if (left > right)
  352. curNode->parent->value.maxGradient = left;
  353. else
  354. curNode->parent->value.maxGradient = right;
  355. if (find_value_min_value(&curNode->parent->value) >
  356. curNode->parent->value.maxGradient)
  357. curNode->parent->value.maxGradient =
  358. find_value_min_value(&curNode->parent->value);
  359. }
  360. else {
  361. break;
  362. }
  363. curNode = curNode->parent;
  364. }
  365. /*fix augmentation for x */
  366. tmpMax =
  367. toFix->left->value.maxGradient >
  368. toFix->right->value.maxGradient ? toFix->left->value.
  369. maxGradient : toFix->right->value.maxGradient;
  370. if (tmpMax > find_value_min_value(&toFix->value))
  371. toFix->value.maxGradient = tmpMax;
  372. else
  373. toFix->value.maxGradient = find_value_min_value(&toFix->value);
  374. /*13-15 */
  375. if (y != NIL && y != z) {
  376. double zGradient = find_value_min_value(&z->value);
  377. z->value.key = y->value.key;
  378. z->value.gradient[0] = y->value.gradient[0];
  379. z->value.gradient[1] = y->value.gradient[1];
  380. z->value.gradient[2] = y->value.gradient[2];
  381. z->value.angle[0] = y->value.angle[0];
  382. z->value.angle[1] = y->value.angle[1];
  383. z->value.angle[2] = y->value.angle[2];
  384. toFix = z;
  385. /*fix augmentation */
  386. tmpMax =
  387. toFix->left->value.maxGradient >
  388. toFix->right->value.maxGradient ? toFix->left->value.
  389. maxGradient : toFix->right->value.maxGradient;
  390. if (tmpMax > find_value_min_value(&toFix->value))
  391. toFix->value.maxGradient = tmpMax;
  392. else
  393. toFix->value.maxGradient = find_value_min_value(&toFix->value);
  394. while (z->parent != NIL) {
  395. if (z->parent->value.maxGradient == zGradient) {
  396. if (find_value_min_value(&z->parent->value) != zGradient &&
  397. (!(z->parent->left->value.maxGradient == zGradient &&
  398. z->parent->right->value.maxGradient == zGradient))) {
  399. left = find_max_value(z->parent->left);
  400. right = find_max_value(z->parent->right);
  401. if (left > right)
  402. z->parent->value.maxGradient = left;
  403. else
  404. z->parent->value.maxGradient = right;
  405. if (find_value_min_value(&z->parent->value) >
  406. z->parent->value.maxGradient)
  407. z->parent->value.maxGradient =
  408. find_value_min_value(&z->parent->value);
  409. }
  410. }
  411. else {
  412. if (z->value.maxGradient > z->parent->value.maxGradient)
  413. z->parent->value.maxGradient = z->value.maxGradient;
  414. }
  415. z = z->parent;
  416. }
  417. }
  418. /*16-17 */
  419. if (y->color == RB_BLACK && x != NIL)
  420. rb_delete_fixup(root, x);
  421. /*18 */
  422. G_free(y);
  423. return;
  424. }
  425. /*fix the rb tree after deletion */
  426. void rb_delete_fixup(TreeNode ** root, TreeNode * x)
  427. {
  428. TreeNode *w;
  429. while (x != *root && x->color == RB_BLACK) {
  430. if (x == x->parent->left) {
  431. w = x->parent->right;
  432. if (w->color == RB_RED) {
  433. w->color = RB_BLACK;
  434. x->parent->color = RB_RED;
  435. left_rotate(root, x->parent);
  436. w = x->parent->right;
  437. }
  438. if (w == NIL) {
  439. x = x->parent;
  440. continue;
  441. }
  442. if (w->left->color == RB_BLACK && w->right->color == RB_BLACK) {
  443. w->color = RB_RED;
  444. x = x->parent;
  445. }
  446. else {
  447. if (w->right->color == RB_BLACK) {
  448. w->left->color = RB_BLACK;
  449. w->color = RB_RED;
  450. right_rotate(root, w);
  451. w = x->parent->right;
  452. }
  453. w->color = x->parent->color;
  454. x->parent->color = RB_BLACK;
  455. w->right->color = RB_BLACK;
  456. left_rotate(root, x->parent);
  457. x = *root;
  458. }
  459. }
  460. else { /*(x==x->parent->right) */
  461. w = x->parent->left;
  462. if (w->color == RB_RED) {
  463. w->color = RB_BLACK;
  464. x->parent->color = RB_RED;
  465. right_rotate(root, x->parent);
  466. w = x->parent->left;
  467. }
  468. if (w == NIL) {
  469. x = x->parent;
  470. continue;
  471. }
  472. if (w->right->color == RB_BLACK && w->left->color == RB_BLACK) {
  473. w->color = RB_RED;
  474. x = x->parent;
  475. }
  476. else {
  477. if (w->left->color == RB_BLACK) {
  478. w->right->color = RB_BLACK;
  479. w->color = RB_RED;
  480. left_rotate(root, w);
  481. w = x->parent->left;
  482. }
  483. w->color = x->parent->color;
  484. x->parent->color = RB_BLACK;
  485. w->left->color = RB_BLACK;
  486. right_rotate(root, x->parent);
  487. x = *root;
  488. }
  489. }
  490. }
  491. x->color = RB_BLACK;
  492. return;
  493. }
  494. /*find the min value in the given tree value */
  495. double find_value_min_value(TreeValue * v)
  496. {
  497. if (v->gradient[0] < v->gradient[1]) {
  498. if (v->gradient[0] < v->gradient[2])
  499. return v->gradient[0];
  500. else
  501. return v->gradient[2];
  502. }
  503. else {
  504. if (v->gradient[1] < v->gradient[2])
  505. return v->gradient[1];
  506. else
  507. return v->gradient[2];
  508. }
  509. return v->gradient[0];
  510. }
  511. /*find the max value in the given tree
  512. //you need to provide a compare function to compare the nodes */
  513. double find_max_value(TreeNode * root)
  514. {
  515. if (!root)
  516. return SMALLEST_GRADIENT;
  517. assert(root);
  518. /*assert(root->value.maxGradient != SMALLEST_GRADIENT);
  519. //LT: this shoudl be fixed
  520. //if (root->value.maxGradient != SMALLEST_GRADIENT) */
  521. return root->value.maxGradient;
  522. }
  523. /* find max within the max key */
  524. double find_max_value_within_key(TreeNode * root, double maxKey, double angle, double gradient)
  525. {
  526. TreeNode *keyNode = search_for_node(root, maxKey);
  527. if (keyNode == NIL) {
  528. /*fprintf(stderr, "key node not found. error occurred!\n");
  529. //there is no point in the structure with key < maxKey */
  530. /*node not found */
  531. G_fatal_error(_("Attempt to find node with key=%f failed"), maxKey);
  532. return SMALLEST_GRADIENT;
  533. }
  534. TreeNode *currNode = keyNode;
  535. double max = SMALLEST_GRADIENT;
  536. double tmpMax;
  537. double curr_gradient;
  538. while (currNode->parent != NIL) {
  539. if (currNode == currNode->parent->right) { /*its the right node of its parent; */
  540. tmpMax = find_max_value(currNode->parent->left);
  541. if (tmpMax > max)
  542. max = tmpMax;
  543. if (find_value_min_value(&currNode->parent->value) > max)
  544. max = find_value_min_value(&currNode->parent->value);
  545. }
  546. currNode = currNode->parent;
  547. }
  548. if (max > gradient)
  549. return max;
  550. /* traverse all nodes with smaller distance */
  551. max = SMALLEST_GRADIENT;
  552. currNode = keyNode;
  553. while (currNode != NIL) {
  554. int checkme = (currNode->value.angle[0] <= angle &&
  555. currNode->value.angle[2] >= angle);
  556. if (!checkme && currNode->value.key > 0) {
  557. G_warning(_("Angles outside angle %.4f"), angle);
  558. G_warning(_("ENTER angle %.4f"), currNode->value.angle[0]);
  559. G_warning(_("CENTER angle %.4f"), currNode->value.angle[1]);
  560. G_warning(_("EXIT angle %.4f"), currNode->value.angle[2]);
  561. G_warning(_("ENTER gradient %.4f"), currNode->value.gradient[0]);
  562. G_warning(_("CENTER gradient %.4f"), currNode->value.gradient[1]);
  563. G_warning(_("EXIT gradient %.4f"), currNode->value.gradient[2]);
  564. }
  565. if (currNode->value.key > maxKey) {
  566. G_fatal_error(_("current dist too large %.4f > %.4f"), currNode->value.key, maxKey);
  567. }
  568. if (checkme && currNode != keyNode) {
  569. if (angle < currNode->value.angle[1]) {
  570. curr_gradient = currNode->value.gradient[1] +
  571. (currNode->value.gradient[0] - currNode->value.gradient[1]) *
  572. (currNode->value.angle[1] - angle) /
  573. (currNode->value.angle[1] - currNode->value.angle[0]);
  574. }
  575. else if (angle > currNode->value.angle[1]) {
  576. curr_gradient = currNode->value.gradient[1] +
  577. (currNode->value.gradient[2] - currNode->value.gradient[1]) *
  578. (angle - currNode->value.angle[1]) /
  579. (currNode->value.angle[2] - currNode->value.angle[1]);
  580. }
  581. else /* angle == currNode->value.angle[1] */
  582. curr_gradient = currNode->value.gradient[1];
  583. if (curr_gradient > max)
  584. max = curr_gradient;
  585. if (max > gradient)
  586. return max;
  587. }
  588. /* get next smaller key */
  589. if (currNode->left != NIL) {
  590. currNode = currNode->left;
  591. while (currNode->right != NIL)
  592. currNode = currNode->right;
  593. }
  594. else {
  595. /* at smallest item in this branch, go back up */
  596. TreeNode *lastNode;
  597. do {
  598. lastNode = currNode;
  599. currNode = currNode->parent;
  600. } while (currNode != NIL && lastNode == currNode->left);
  601. }
  602. }
  603. return max;
  604. /* old code assuming flat cells */
  605. while (keyNode->parent != NIL) {
  606. if (keyNode == keyNode->parent->right) { /*its the right node of its parent; */
  607. tmpMax = find_max_value(keyNode->parent->left);
  608. if (tmpMax > max)
  609. max = tmpMax;
  610. if (keyNode->parent->value.gradient[1] > max)
  611. max = keyNode->parent->value.gradient[1];
  612. }
  613. keyNode = keyNode->parent;
  614. }
  615. return max;
  616. }
  617. void left_rotate(TreeNode ** root, TreeNode * x)
  618. {
  619. TreeNode *y;
  620. y = x->right;
  621. /*maintain augmentation */
  622. double tmpMax;
  623. /*fix x */
  624. tmpMax = x->left->value.maxGradient > y->left->value.maxGradient ?
  625. x->left->value.maxGradient : y->left->value.maxGradient;
  626. if (tmpMax > find_value_min_value(&x->value))
  627. x->value.maxGradient = tmpMax;
  628. else
  629. x->value.maxGradient = find_value_min_value(&x->value);
  630. /*fix y */
  631. tmpMax = x->value.maxGradient > y->right->value.maxGradient ?
  632. x->value.maxGradient : y->right->value.maxGradient;
  633. if (tmpMax > find_value_min_value(&y->value))
  634. y->value.maxGradient = tmpMax;
  635. else
  636. y->value.maxGradient = find_value_min_value(&y->value);
  637. /*left rotation
  638. //see pseudocode on page 278 in CLRS */
  639. x->right = y->left; /*turn y's left subtree into x's right subtree */
  640. y->left->parent = x;
  641. y->parent = x->parent; /*link x's parent to y */
  642. if (x->parent == NIL) {
  643. *root = y;
  644. }
  645. else {
  646. if (x == x->parent->left)
  647. x->parent->left = y;
  648. else
  649. x->parent->right = y;
  650. }
  651. y->left = x;
  652. x->parent = y;
  653. return;
  654. }
  655. void right_rotate(TreeNode ** root, TreeNode * y)
  656. {
  657. TreeNode *x;
  658. x = y->left;
  659. /*maintain augmentation
  660. //fix y */
  661. double tmpMax;
  662. tmpMax = x->right->value.maxGradient > y->right->value.maxGradient ?
  663. x->right->value.maxGradient : y->right->value.maxGradient;
  664. if (tmpMax > find_value_min_value(&y->value))
  665. y->value.maxGradient = tmpMax;
  666. else
  667. y->value.maxGradient = find_value_min_value(&y->value);
  668. /*fix x */
  669. tmpMax = x->left->value.maxGradient > y->value.maxGradient ?
  670. x->left->value.maxGradient : y->value.maxGradient;
  671. if (tmpMax > find_value_min_value(&x->value))
  672. x->value.maxGradient = tmpMax;
  673. else
  674. x->value.maxGradient = find_value_min_value(&x->value);
  675. /*ratation */
  676. y->left = x->right;
  677. x->right->parent = y;
  678. x->parent = y->parent;
  679. if (y->parent == NIL) {
  680. *root = x;
  681. }
  682. else {
  683. if (y->parent->left == y)
  684. y->parent->left = x;
  685. else
  686. y->parent->right = x;
  687. }
  688. x->right = y;
  689. y->parent = x;
  690. return;
  691. }