Advertisement
wandrake

Untitled

Jun 26th, 2011
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.70 KB | None | 0 0
  1. /**
  2.  *  \file dgraph.c
  3.  *
  4.  *  \author Alessandro Ambrosano
  5.  *
  6.  *  Si dichiara che il contenuto di questo file è in ogni sua parte
  7.  *  opera originale dell'autore.
  8.  */
  9.  
  10. #include "heap.h"
  11.  
  12. heap_t* heap_new() {
  13.     heap_t* ret;
  14.  
  15.     CHECK_ENOMEM((ret = (heap_t*)malloc(sizeof(heap_t))) == NULL, NULL);
  16.  
  17.     ret->nval = 0;
  18.     ret->maxval = 0;
  19.     ret->values = NULL;
  20.  
  21.     return ret;
  22. }
  23.  
  24. int heap_add (heap_t* q, wstatus_t* status, int weight) {
  25.     wstatus_t* temp;
  26.     int i, father;
  27.  
  28.     CHECK_EINVAL(q == NULL || weight < 0, -1);
  29.  
  30.     q->nval++;
  31.  
  32.     /* Controllo se ho bisogno di riallocare, se il numero di elementi è maggiore del massimo raddoppio
  33.      * la dimensione del vettore dei valori */
  34.     if (q->nval > q->maxval) {
  35.         /* Nella heap_extract() dimezzo il valore di q->maxval ogni volta che il numero di elementi
  36.          * nello heap è meno della metà di q->maxval, quando arrivo a 0, ho bisogno di riallocare
  37.          * un solo elemento */
  38.         if (q->maxval == 0) {
  39.             CHECK_ENOMEM((q->values = (wstatus_t**)realloc(q->values, sizeof(wstatus_t*))) == NULL, -1);
  40.             q->maxval++;
  41.         }
  42.         else {
  43.             CHECK_ENOMEM((q->values = (wstatus_t**)realloc(q->values, 2*(q->maxval)*sizeof(wstatus_t*))) == NULL, -1);
  44.             q->maxval *= 2;
  45.         }
  46.     }
  47.  
  48.     CHECK_ENOMEM((q->values[q->nval-1] = (wstatus_t*)malloc(sizeof(wstatus_t))) == NULL, -1);
  49.  
  50.     /* Inserisco i dati del nuovo nodo e riordino lo heap */
  51.     q->values[q->nval-1]->status = status->status;
  52.     q->values[q->nval-1]->weight = weight;
  53.  
  54.     i = q->nval-1;
  55.  
  56.     father = (i+1)/2-1;
  57.     while (i > 1 && q->values[i]->weight < q->values[father]->weight) {
  58.         temp = q->values[i];
  59.         q->values[i] = q->values[father];
  60.         q->values[father] = temp;
  61.         i = father;
  62.         father = (i+1)/2-1;
  63.     }
  64.  
  65.     return 0;
  66. }
  67.  
  68. /* int heap_exists (heap_t* q, int label) {
  69.     int i;
  70.  
  71.     i = 0;
  72.     while (i < q->nval) {
  73.         if (q->values[i]->label == label) return 1;
  74.         i++;
  75.     }
  76.     return 0;
  77. } */
  78.  
  79. void heap_heapify (heap_t* h, int from) {
  80.     int left, right, tinyest;
  81.     wstatus_t* temp;
  82.  
  83.     left = (from+1)*2-1;
  84.     right = (from+1)*2;
  85.     tinyest = from;
  86.  
  87.     /* Cerco il minore tra il padre e i figli */
  88.     if (left < h->nval && h->values[left]->weight < h->values[from]->weight) tinyest = left;
  89.     if (right < h->nval && h->values[right]->weight < h->values[from]->weight) tinyest = right;
  90.  
  91.     /* Se il minore non è il padre, scambio il padre con i minori e riapplico
  92.      * la procedura al sottoalbero in cui sono intervenuto */
  93.     if (tinyest != from) {
  94.         temp = h->values[from];
  95.         h->values[from] = h->values[tinyest];
  96.         h->values[tinyest] = temp;
  97.         heap_heapify(h, tinyest);
  98.     }
  99. }
  100.  
  101. wstatus_t* heap_extract(heap_t* h) {
  102.     wstatus_t* ret;
  103.  
  104.     CHECK_EINVAL(h == NULL || h->nval == 0, NULL);
  105.  
  106.     /* Salvo il primo elemento dello heap e lo rimpiazzo con l'ultimo */
  107.     ret = h->values[0];
  108.     h->nval--;
  109.     h->values[0] = h->values[h->nval];
  110.  
  111.     /* Riordino lo heap */
  112.     heap_heapify(h, 0);
  113.  
  114.     if (h->nval == 0) {
  115.         free(h->values);
  116.         h->values = NULL;
  117.         h->maxval = 0;
  118.     }
  119.     else if (h->nval == h->maxval/2) {
  120.         h->values = (wstatus_t**)realloc(h->values, (h->maxval/2)*sizeof(wstatus_t*));
  121.         h->maxval = h->maxval/2;
  122.     }
  123.  
  124.     return ret;
  125. }
  126.  
  127. #ifdef ASDFIAOETRWQETGQOER
  128. int heap_reduce(heap_t* q, int label, int weight) {
  129.     int i, father;
  130.     wstatus_t* temp;
  131.  
  132.     i = 0;
  133.     /* Cerco il nodo label, se non lo trovo do errore */
  134.     while (i < q->nval && q->values[i]->label != label) i++;
  135.  
  136.     if (i == q->nval) return -1;
  137.  
  138.     q->values[i]->weight = weight;
  139.  
  140.     /* Una volta aggiornato lo heap, lo riordino */
  141.     /* Mi va bene non considerare il caso infinito, infatti ogni volta che vado a ridurre
  142.      * provengo da un nodo che ha distanza finita, e sommo un valore finito */
  143.     father = (i+1)/2-1;
  144.     while (i > 0 && q->values[i]->weight > q->values[father]->weight) {
  145.         temp = q->values[i];
  146.         q->values[i] = q->values[father];
  147.         q->values[father] = temp;
  148.         i = father;
  149.         father = (i+1)/2-1;
  150.     }
  151.  
  152.     return 0;
  153. }
  154. #endif
  155.  
  156. void heap_print (heap_t* q) {
  157.     int i = 0, j = 0;
  158.  
  159.     wstatus_t* w;
  160.     status_t* s;
  161.  
  162.     if (q->nval == 0) printf("CODA VUOTA\n");
  163.     for (i = 0; i < q->nval; i++) {
  164.         w = q->values[i];
  165.         s = w->status;
  166.  
  167.         for (j = 0; j < 9; j++) {
  168.             printf("%d ", s->conf[j]);
  169.         }
  170.         printf("distance: %d\n", w->weight);
  171. /*        printf("node: %d, weight: %f\n", q->values[i]->conf, q->values[i]->distance); */
  172.     }
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement