avlID.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. long howManyID(const avlID_tree root, const long k)
  42. {
  43. avlID_node *nodo = NULL;
  44. nodo = avlID_find(root, k);
  45. if (nodo == NULL)
  46. return 0;
  47. else
  48. return nodo->counter;
  49. }
  50. avlID_node *avlID_find(const avlID_tree root, const long k)
  51. {
  52. avlID_node *p = NULL;
  53. int d = 0;
  54. if (root == NULL)
  55. return NULL;
  56. return avlID_individua(root, k, &p, &d);
  57. }
  58. long avlID_sub(avlID_tree * root, const long k)
  59. {
  60. long ris = 0;
  61. avlID_node *nodo = NULL;
  62. nodo = avlID_find(*root, k);
  63. if (nodo != NULL) {
  64. ris = nodo->counter;
  65. nodo->counter = 0;
  66. }
  67. return ris;
  68. }
  69. int avlID_add(avlID_tree * root, const long k, const long n)
  70. {
  71. int d = 0; /* -1 if the new node is the left child
  72. 1 if the new node is the right child */
  73. int pos1 = 0, pos2 = 0;
  74. int rotation = 0; /* rotation type to balance tree */
  75. avlID_node *node_temp = NULL;
  76. avlID_node *critical = NULL;
  77. avlID_node *p = NULL; /* father pointer of new node */
  78. if ((root == NULL) || (*root == NULL))
  79. return AVL_ERR;
  80. /* find where insert the new node */
  81. node_temp = avlID_individua(*root, k, &p, &d);
  82. if (node_temp != NULL) {
  83. node_temp->counter = node_temp->counter + n;
  84. return AVL_PRES; /* key already exists in the tree, only update the counter */
  85. }
  86. /* create the new node */
  87. node_temp = avlID_make(k, n);
  88. if (node_temp == NULL)
  89. return AVL_ERR;
  90. /* insert the new node */
  91. node_temp->father = p;
  92. if (d == -1)
  93. p->left_child = node_temp;
  94. else {
  95. if (d == 1)
  96. p->right_child = node_temp;
  97. else {
  98. G_free(node_temp);
  99. return AVL_ERR;
  100. }
  101. }
  102. /* if necessary balance the tree */
  103. critical = critical_node(node_temp, &pos1, &pos2, NULL);
  104. if (critical == NULL)
  105. return AVL_ADD; /* not necessary */
  106. /* balance */
  107. rotation = (pos1 * 10) + pos2;
  108. switch (rotation) { /* rotate */
  109. case AVL_SS:
  110. avlID_rotation_ll(critical);
  111. break;
  112. case AVL_SD:
  113. avlID_rotation_lr(critical);
  114. break;
  115. case AVL_DS:
  116. avlID_rotation_rl(critical);
  117. break;
  118. case AVL_DD:
  119. avlID_rotation_rr(critical);
  120. break;
  121. default:
  122. G_fatal_error("avl, avlID_add: balancing error\n");
  123. return AVL_ERR;
  124. }
  125. /* if after rotation there is a new root update the root pointer */
  126. while ((*root)->father != NULL)
  127. *root = (*root)->father;
  128. return AVL_ADD;
  129. }
  130. long avlID_to_array(avlID_node * root, long i, avlID_table * a)
  131. {
  132. if (root != NULL) {
  133. i = avlID_to_array(root->left_child, i, a);
  134. if (a == NULL)
  135. G_fatal_error("avl, avlID_to_array: null value");
  136. else {
  137. a[i] = G_malloc(sizeof(avlID_tableRow));
  138. a[i]->k = root->id;
  139. a[i]->tot = root->counter;
  140. i++;
  141. i = avlID_to_array(root->right_child, i, a);
  142. }
  143. }
  144. return i;
  145. }
  146. /* private functions */
  147. static avlID_node *avlID_individua(const avlID_tree root, const long k,
  148. avlID_node ** father, int *direction)
  149. {
  150. if (root == NULL)
  151. return NULL;
  152. if (root->id == k)
  153. return root;
  154. else {
  155. if (root->id > k) {
  156. *father = root;
  157. *direction = -1;
  158. return avlID_individua(root->left_child, k, father, direction);
  159. }
  160. else { /* key < k */
  161. *father = root;
  162. *direction = 1;
  163. return avlID_individua(root->right_child, k, father, direction);
  164. }
  165. }
  166. }
  167. static int avlID_height(const avlID_tree root)
  168. {
  169. if (root == NULL)
  170. return -1;
  171. else {
  172. int tmp1 = avlID_height(root->left_child);
  173. int tmp2 = avlID_height(root->right_child);
  174. return (1 + ((tmp1 > tmp2) ? tmp1 : tmp2));
  175. }
  176. }
  177. static avlID_node *critical_node(avlID_node * added, int *pos1, int *pos2,
  178. const avlID_node * prec)
  179. {
  180. int fdb = 0;
  181. if (added == NULL)
  182. return NULL;
  183. if (prec == NULL)
  184. *pos1 = *pos2 = 0;
  185. else {
  186. *pos2 = *pos1;
  187. if (prec == added->left_child)
  188. *pos1 = AVL_S;
  189. else
  190. *pos1 = AVL_D; /* prec == added->right_child */
  191. }
  192. fdb =
  193. abs(avlID_height(added->left_child) -
  194. avlID_height(added->right_child));
  195. if (fdb > 1)
  196. return added;
  197. else {
  198. prec = added;
  199. return critical_node(added->father, pos1, pos2, prec);
  200. }
  201. }
  202. void avlID_rotation_ll(avlID_node * critical)
  203. {
  204. avlID_node *b = NULL;
  205. avlID_node *r = critical;
  206. avlID_node *s = critical->left_child;
  207. s->father = r->father;
  208. if (r->father != NULL) {
  209. if ((r->father)->left_child == r)
  210. (r->father)->left_child = s;
  211. else
  212. (r->father)->right_child = s;
  213. }
  214. b = s->right_child;
  215. s->right_child = r;
  216. r->father = s;
  217. r->left_child = b;
  218. if (b != NULL)
  219. b->father = r;
  220. }
  221. void avlID_rotation_rr(avlID_node * critical)
  222. {
  223. avlID_node *b = NULL;
  224. avlID_node *r = critical;
  225. avlID_node *s = critical->right_child;
  226. s->father = r->father;
  227. if (r->father != NULL) {
  228. if ((r->father)->left_child == r)
  229. (r->father)->left_child = s;
  230. else
  231. (r->father)->right_child = s;
  232. }
  233. b = s->left_child;
  234. s->left_child = r;
  235. r->father = s;
  236. r->right_child = b;
  237. if (b != NULL)
  238. b->father = r;
  239. }
  240. void avlID_rotation_lr(avlID_node * critical)
  241. {
  242. avlID_node *b = NULL;
  243. avlID_node *g = NULL;
  244. avlID_node *r = critical;
  245. avlID_node *s = critical->left_child;
  246. avlID_node *t = (critical->left_child)->right_child;
  247. t->father = r->father;
  248. if (r->father != NULL) {
  249. if ((r->father)->left_child == r)
  250. (r->father)->left_child = t;
  251. else
  252. (r->father)->right_child = t;
  253. }
  254. b = t->left_child;
  255. g = t->right_child;
  256. t->left_child = s;
  257. t->right_child = r;
  258. r->father = t;
  259. s->father = t;
  260. s->right_child = b;
  261. r->left_child = g;
  262. if (b != NULL)
  263. b->father = s;
  264. if (g != NULL)
  265. g->father = r;
  266. }
  267. void avlID_rotation_rl(avlID_node * critical)
  268. {
  269. avlID_node *b = NULL;
  270. avlID_node *g = NULL;
  271. avlID_node *r = critical;
  272. avlID_node *s = critical->right_child;
  273. avlID_node *t = (critical->right_child)->left_child;
  274. t->father = r->father;
  275. if (r->father != NULL) {
  276. if ((r->father)->left_child == r)
  277. (r->father)->left_child = t;
  278. else
  279. (r->father)->right_child = t;
  280. }
  281. b = t->left_child;
  282. g = t->right_child;
  283. t->left_child = r;
  284. t->right_child = s;
  285. r->father = t;
  286. s->father = t;
  287. r->right_child = b;
  288. s->left_child = g;
  289. if (b != NULL)
  290. b->father = r;
  291. if (g != NULL)
  292. g->father = s;
  293. }