123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- /*
- * \AUTHOR: Serena Pallecchi student of Computer Science University of Pisa (Italy)
- * Commission from Faunalia Pontedera (PI) www.faunalia.it
- *
- * This program is free software under the GPL (>=v2)
- * Read the COPYING file that comes with GRASS for details.
- *
- */
- #include <stdlib.h>
- #include <fcntl.h>
- #include <math.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include "defs.h"
- #include "avlDefs.h"
- #include "avlID.h"
- static avlID_node *avlID_individua(const avlID_tree root, const long k,
- avlID_node ** father, int *direction);
- static int avlID_height(const avlID_tree root);
- static avlID_node *critical_node(avlID_node * added, int *pos1, int *pos2,
- const avlID_node * prec);
- void avlID_rotation_ll(avlID_node * critical);
- void avlID_rotation_lr(avlID_node * critical);
- void avlID_rotation_rl(avlID_node * critical);
- void avlID_rotation_rr(avlID_node * critical);
- avlID_tree avlID_make(const long k, const long n)
- {
- avlID_node *root = NULL; /* root pointer */
- /* create root */
- root = G_malloc(sizeof(avlID_node));
- if (root == NULL)
- return NULL;
- /* initialize root */
- root->right_child = NULL;
- root->left_child = NULL;
- root->father = NULL;
- root->counter = n;
- root->id = k;
- return root;
- }
- long howManyID(const avlID_tree root, const long k)
- {
- avlID_node *nodo = NULL;
- nodo = avlID_find(root, k);
- if (nodo == NULL)
- return 0;
- else
- return nodo->counter;
- }
- avlID_node *avlID_find(const avlID_tree root, const long k)
- {
- avlID_node *p = NULL;
- int d = 0;
- if (root == NULL)
- return NULL;
- return avlID_individua(root, k, &p, &d);
- }
- long avlID_sub(avlID_tree * root, const long k)
- {
- long ris = 0;
- avlID_node *nodo = NULL;
- nodo = avlID_find(*root, k);
- if (nodo != NULL) {
- ris = nodo->counter;
- nodo->counter = 0;
- }
- return ris;
- }
- int avlID_add(avlID_tree * root, const long k, const long n)
- {
- int d = 0; /* -1 if the new node is the left child
- 1 if the new node is the right child */
- int pos1 = 0, pos2 = 0;
- int rotation = 0; /* rotation type to balance tree */
- avlID_node *node_temp = NULL;
- avlID_node *critical = NULL;
- avlID_node *p = NULL; /* father pointer of new node */
- if ((root == NULL) || (*root == NULL))
- return AVL_ERR;
- /* find where insert the new node */
- node_temp = avlID_individua(*root, k, &p, &d);
- if (node_temp != NULL) {
- node_temp->counter = node_temp->counter + n;
- return AVL_PRES; /* key already exists in the tree, only update the counter */
- }
- /* create the new node */
- node_temp = avlID_make(k, n);
- if (node_temp == NULL)
- return AVL_ERR;
- /* insert the new node */
- node_temp->father = p;
- if (d == -1)
- p->left_child = node_temp;
- else {
- if (d == 1)
- p->right_child = node_temp;
- else {
- G_free(node_temp);
- return AVL_ERR;
- }
- }
- /* if necessary balance the tree */
- critical = critical_node(node_temp, &pos1, &pos2, NULL);
- if (critical == NULL)
- return AVL_ADD; /* not necessary */
- /* balance */
- rotation = (pos1 * 10) + pos2;
- switch (rotation) { /* rotate */
- case AVL_SS:
- avlID_rotation_ll(critical);
- break;
- case AVL_SD:
- avlID_rotation_lr(critical);
- break;
- case AVL_DS:
- avlID_rotation_rl(critical);
- break;
- case AVL_DD:
- avlID_rotation_rr(critical);
- break;
- default:
- G_fatal_error("avl, avlID_add: balancing error\n");
- return AVL_ERR;
- }
- /* if after rotation there is a new root update the root pointer */
- while ((*root)->father != NULL)
- *root = (*root)->father;
- return AVL_ADD;
- }
- long avlID_to_array(avlID_node * root, long i, avlID_table * a)
- {
- if (root != NULL) {
- i = avlID_to_array(root->left_child, i, a);
- if (a == NULL)
- G_fatal_error("avl, avlID_to_array: null value");
- else {
- a[i] = G_malloc(sizeof(avlID_tableRow));
- a[i]->k = root->id;
- a[i]->tot = root->counter;
- i++;
- i = avlID_to_array(root->right_child, i, a);
- }
- }
- return i;
- }
- /* private functions */
- static avlID_node *avlID_individua(const avlID_tree root, const long k,
- avlID_node ** father, int *direction)
- {
- if (root == NULL)
- return NULL;
- if (root->id == k)
- return root;
- else {
- if (root->id > k) {
- *father = root;
- *direction = -1;
- return avlID_individua(root->left_child, k, father, direction);
- }
- else { /* key < k */
- *father = root;
- *direction = 1;
- return avlID_individua(root->right_child, k, father, direction);
- }
- }
- }
- static int avlID_height(const avlID_tree root)
- {
- if (root == NULL)
- return -1;
- else {
- int tmp1 = avlID_height(root->left_child);
- int tmp2 = avlID_height(root->right_child);
- return (1 + ((tmp1 > tmp2) ? tmp1 : tmp2));
- }
- }
- static avlID_node *critical_node(avlID_node * added, int *pos1, int *pos2,
- const avlID_node * prec)
- {
- int fdb = 0;
- if (added == NULL)
- return NULL;
- if (prec == NULL)
- *pos1 = *pos2 = 0;
- else {
- *pos2 = *pos1;
- if (prec == added->left_child)
- *pos1 = AVL_S;
- else
- *pos1 = AVL_D; /* prec == added->right_child */
- }
- fdb =
- abs(avlID_height(added->left_child) -
- avlID_height(added->right_child));
- if (fdb > 1)
- return added;
- else {
- prec = added;
- return critical_node(added->father, pos1, pos2, prec);
- }
- }
- void avlID_rotation_ll(avlID_node * critical)
- {
- avlID_node *b = NULL;
- avlID_node *r = critical;
- avlID_node *s = critical->left_child;
- s->father = r->father;
- if (r->father != NULL) {
- if ((r->father)->left_child == r)
- (r->father)->left_child = s;
- else
- (r->father)->right_child = s;
- }
- b = s->right_child;
- s->right_child = r;
- r->father = s;
- r->left_child = b;
- if (b != NULL)
- b->father = r;
- }
- void avlID_rotation_rr(avlID_node * critical)
- {
- avlID_node *b = NULL;
- avlID_node *r = critical;
- avlID_node *s = critical->right_child;
- s->father = r->father;
- if (r->father != NULL) {
- if ((r->father)->left_child == r)
- (r->father)->left_child = s;
- else
- (r->father)->right_child = s;
- }
- b = s->left_child;
- s->left_child = r;
- r->father = s;
- r->right_child = b;
- if (b != NULL)
- b->father = r;
- }
- void avlID_rotation_lr(avlID_node * critical)
- {
- avlID_node *b = NULL;
- avlID_node *g = NULL;
- avlID_node *r = critical;
- avlID_node *s = critical->left_child;
- avlID_node *t = (critical->left_child)->right_child;
- t->father = r->father;
- if (r->father != NULL) {
- if ((r->father)->left_child == r)
- (r->father)->left_child = t;
- else
- (r->father)->right_child = t;
- }
- b = t->left_child;
- g = t->right_child;
- t->left_child = s;
- t->right_child = r;
- r->father = t;
- s->father = t;
- s->right_child = b;
- r->left_child = g;
- if (b != NULL)
- b->father = s;
- if (g != NULL)
- g->father = r;
- }
- void avlID_rotation_rl(avlID_node * critical)
- {
- avlID_node *b = NULL;
- avlID_node *g = NULL;
- avlID_node *r = critical;
- avlID_node *s = critical->right_child;
- avlID_node *t = (critical->right_child)->left_child;
- t->father = r->father;
- if (r->father != NULL) {
- if ((r->father)->left_child == r)
- (r->father)->left_child = t;
- else
- (r->father)->right_child = t;
- }
- b = t->left_child;
- g = t->right_child;
- t->left_child = r;
- t->right_child = s;
- r->father = t;
- s->father = t;
- r->right_child = b;
- s->left_child = g;
- if (b != NULL)
- b->father = r;
- if (g != NULL)
- g->father = s;
- }
|