avlID.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * \AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
  3. * Commission from Faunalia Pontedera (PI) www.faunalia.it
  4. *
  5. * This program is free software under the GPL (>=v2)
  6. * Read the COPYING file that comes with GRASS for details.
  7. *
  8. */
  9. #include <stdlib.h>
  10. #include <fcntl.h>
  11. #include <math.h>
  12. #include <grass/gis.h>
  13. #include <grass/glocale.h>
  14. #include "defs.h"
  15. #include "avlDefs.h"
  16. #include "avlID.h"
  17. static avlID_node *avlID_individua(const avlID_tree root, const long k,
  18. avlID_node ** father, int *direction);
  19. static int avlID_height(const avlID_tree root);
  20. static avlID_node *critical_node(avlID_node * added, int *pos1, int *pos2,
  21. const avlID_node * prec);
  22. void avlID_rotation_ll(avlID_node * critical);
  23. void avlID_rotation_lr(avlID_node * critical);
  24. void avlID_rotation_rl(avlID_node * critical);
  25. void avlID_rotation_rr(avlID_node * critical);
  26. avlID_tree avlID_make(const long k, const long n)
  27. {
  28. avlID_node *root = NULL; /* root pointer */
  29. /* create root */
  30. root = G_malloc(sizeof(avlID_node));
  31. if (root == NULL)
  32. return NULL;
  33. /* initialize root */
  34. root->right_child = NULL;
  35. root->left_child = NULL;
  36. root->father = NULL;
  37. root->counter = n;
  38. root->id = k;
  39. return root;
  40. }
  41. void avlID_destroy(avlID_tree root)
  42. {
  43. struct avlID_node *it;
  44. struct avlID_node *save = root;
  45. /*
  46. Rotate away the left links so that
  47. we can treat this like the destruction
  48. of a linked list
  49. */
  50. while((it = save) != NULL) {
  51. if (it->left_child == NULL) {
  52. /* No left links, just kill the node and move on */
  53. save = it->right_child;
  54. G_free(it);
  55. it = NULL;
  56. }
  57. else {
  58. /* Rotate away the left link and check again */
  59. save = it->left_child;
  60. it->left_child = save->right_child;
  61. save->right_child = it;
  62. }
  63. }
  64. }
  65. long howManyID(const avlID_tree root, const long k)
  66. {
  67. avlID_node *nodo = NULL;
  68. nodo = avlID_find(root, k);
  69. if (nodo == NULL)
  70. return 0;
  71. else
  72. return nodo->counter;
  73. }
  74. avlID_node *avlID_find(const avlID_tree root, const long k)
  75. {
  76. avlID_node *p = NULL;
  77. int d = 0;
  78. if (root == NULL)
  79. return NULL;
  80. return avlID_individua(root, k, &p, &d);
  81. }
  82. long avlID_sub(avlID_tree * root, const long k)
  83. {
  84. long ris = 0;
  85. avlID_node *nodo = NULL;
  86. nodo = avlID_find(*root, k);
  87. if (nodo != NULL) {
  88. ris = nodo->counter;
  89. nodo->counter = 0;
  90. }
  91. return ris;
  92. }
  93. int avlID_add(avlID_tree * root, const long k, const long n)
  94. {
  95. int d = 0; /* -1 if the new node is the left child
  96. 1 if the new node is the right child */
  97. int pos1 = 0, pos2 = 0;
  98. int rotation = 0; /* rotation type to balance tree */
  99. avlID_node *node_temp = NULL;
  100. avlID_node *critical = NULL;
  101. avlID_node *p = NULL; /* father pointer of new node */
  102. if ((root == NULL) || (*root == NULL))
  103. return AVL_ERR;
  104. /* find where insert the new node */
  105. node_temp = avlID_individua(*root, k, &p, &d);
  106. if (node_temp != NULL) {
  107. node_temp->counter = node_temp->counter + n;
  108. return AVL_PRES; /* key already exists in the tree, only update the counter */
  109. }
  110. /* create the new node */
  111. node_temp = avlID_make(k, n);
  112. if (node_temp == NULL)
  113. return AVL_ERR;
  114. /* insert the new node */
  115. node_temp->father = p;
  116. if (d == -1)
  117. p->left_child = node_temp;
  118. else {
  119. if (d == 1)
  120. p->right_child = node_temp;
  121. else {
  122. G_free(node_temp);
  123. return AVL_ERR;
  124. }
  125. }
  126. /* if necessary balance the tree */
  127. critical = critical_node(node_temp, &pos1, &pos2, NULL);
  128. if (critical == NULL)
  129. return AVL_ADD; /* not necessary */
  130. /* balance */
  131. rotation = (pos1 * 10) + pos2;
  132. switch (rotation) { /* rotate */
  133. case AVL_SS:
  134. avlID_rotation_ll(critical);
  135. break;
  136. case AVL_SD:
  137. avlID_rotation_lr(critical);
  138. break;
  139. case AVL_DS:
  140. avlID_rotation_rl(critical);
  141. break;
  142. case AVL_DD:
  143. avlID_rotation_rr(critical);
  144. break;
  145. default:
  146. G_fatal_error("avl, avlID_add: balancing error\n");
  147. return AVL_ERR;
  148. }
  149. /* if after rotation there is a new root update the root pointer */
  150. while ((*root)->father != NULL)
  151. *root = (*root)->father;
  152. return AVL_ADD;
  153. }
  154. long avlID_to_array(avlID_node * root, long i, avlID_table * a)
  155. {
  156. if (root != NULL) {
  157. i = avlID_to_array(root->left_child, i, a);
  158. if (a == NULL)
  159. G_fatal_error("avl, avlID_to_array: null value");
  160. else {
  161. a[i] = G_malloc(sizeof(avlID_tableRow));
  162. a[i]->k = root->id;
  163. a[i]->tot = root->counter;
  164. i++;
  165. i = avlID_to_array(root->right_child, i, a);
  166. }
  167. }
  168. return i;
  169. }
  170. /* private functions */
  171. static avlID_node *avlID_individua(const avlID_tree root, const long k,
  172. avlID_node ** father, int *direction)
  173. {
  174. if (root == NULL)
  175. return NULL;
  176. if (root->id == k)
  177. return root;
  178. else {
  179. if (root->id > k) {
  180. *father = root;
  181. *direction = -1;
  182. return avlID_individua(root->left_child, k, father, direction);
  183. }
  184. else { /* key < k */
  185. *father = root;
  186. *direction = 1;
  187. return avlID_individua(root->right_child, k, father, direction);
  188. }
  189. }
  190. }
  191. static int avlID_height(const avlID_tree root)
  192. {
  193. if (root == NULL)
  194. return -1;
  195. else {
  196. int tmp1 = avlID_height(root->left_child);
  197. int tmp2 = avlID_height(root->right_child);
  198. return (1 + ((tmp1 > tmp2) ? tmp1 : tmp2));
  199. }
  200. }
  201. static avlID_node *critical_node(avlID_node * added, int *pos1, int *pos2,
  202. const avlID_node * prec)
  203. {
  204. int fdb = 0;
  205. if (added == NULL)
  206. return NULL;
  207. if (prec == NULL)
  208. *pos1 = *pos2 = 0;
  209. else {
  210. *pos2 = *pos1;
  211. if (prec == added->left_child)
  212. *pos1 = AVL_S;
  213. else
  214. *pos1 = AVL_D; /* prec == added->right_child */
  215. }
  216. fdb =
  217. abs(avlID_height(added->left_child) -
  218. avlID_height(added->right_child));
  219. if (fdb > 1)
  220. return added;
  221. else {
  222. prec = added;
  223. return critical_node(added->father, pos1, pos2, prec);
  224. }
  225. }
  226. void avlID_rotation_ll(avlID_node * critical)
  227. {
  228. avlID_node *b = NULL;
  229. avlID_node *r = critical;
  230. avlID_node *s = critical->left_child;
  231. s->father = r->father;
  232. if (r->father != NULL) {
  233. if ((r->father)->left_child == r)
  234. (r->father)->left_child = s;
  235. else
  236. (r->father)->right_child = s;
  237. }
  238. b = s->right_child;
  239. s->right_child = r;
  240. r->father = s;
  241. r->left_child = b;
  242. if (b != NULL)
  243. b->father = r;
  244. }
  245. void avlID_rotation_rr(avlID_node * critical)
  246. {
  247. avlID_node *b = NULL;
  248. avlID_node *r = critical;
  249. avlID_node *s = critical->right_child;
  250. s->father = r->father;
  251. if (r->father != NULL) {
  252. if ((r->father)->left_child == r)
  253. (r->father)->left_child = s;
  254. else
  255. (r->father)->right_child = s;
  256. }
  257. b = s->left_child;
  258. s->left_child = r;
  259. r->father = s;
  260. r->right_child = b;
  261. if (b != NULL)
  262. b->father = r;
  263. }
  264. void avlID_rotation_lr(avlID_node * critical)
  265. {
  266. avlID_node *b = NULL;
  267. avlID_node *g = NULL;
  268. avlID_node *r = critical;
  269. avlID_node *s = critical->left_child;
  270. avlID_node *t = (critical->left_child)->right_child;
  271. t->father = r->father;
  272. if (r->father != NULL) {
  273. if ((r->father)->left_child == r)
  274. (r->father)->left_child = t;
  275. else
  276. (r->father)->right_child = t;
  277. }
  278. b = t->left_child;
  279. g = t->right_child;
  280. t->left_child = s;
  281. t->right_child = r;
  282. r->father = t;
  283. s->father = t;
  284. s->right_child = b;
  285. r->left_child = g;
  286. if (b != NULL)
  287. b->father = s;
  288. if (g != NULL)
  289. g->father = r;
  290. }
  291. void avlID_rotation_rl(avlID_node * critical)
  292. {
  293. avlID_node *b = NULL;
  294. avlID_node *g = NULL;
  295. avlID_node *r = critical;
  296. avlID_node *s = critical->right_child;
  297. avlID_node *t = (critical->right_child)->left_child;
  298. t->father = r->father;
  299. if (r->father != NULL) {
  300. if ((r->father)->left_child == r)
  301. (r->father)->left_child = t;
  302. else
  303. (r->father)->right_child = t;
  304. }
  305. b = t->left_child;
  306. g = t->right_child;
  307. t->left_child = r;
  308. t->right_child = s;
  309. r->father = t;
  310. s->father = t;
  311. r->right_child = b;
  312. s->left_child = g;
  313. if (b != NULL)
  314. b->father = r;
  315. if (g != NULL)
  316. g->father = s;
  317. }