r_heap.c
Upload User: gzelex
Upload Date: 2007-01-07
Package Size: 707k
Code Size: 6k
Development Platform:

MultiPlatform

  1. /* This file has been automatically generated from "r_heap.w"
  2.    by CTANGLE (Version 3.1 [km2c]) */
  3. #include "r_heap.h"
  4. #include <math.h>
  5. r_heap::r_heap(int c)
  6. {
  7.   C = c;
  8.   B = int (ceil(log(C) / log(2))) + 2;
  9.   buckets = (r_heap_item *) new int[B];
  10.   for (int i = 0; i < B; i++)
  11.     buckets[i] = nil;
  12.   bsize = new int[B];
  13.   u = new int[B];
  14.   bsize[0] = 1;
  15.   bsize[B - 1] = MAXINT;
  16.   for (i = 1; i < B - 1; i++)
  17.     bsize[i] = 1 << (i - 1);
  18.   u[B - 1] = MAXINT; /* this value won't change throughout the
  19.  * computation the other u[] values will be
  20.  * initialized by |insert| */
  21.   si = 0;
  22. }
  23. r_heap::r_heap(const r_heap & rh)
  24. {
  25.   copy_heap(rh);
  26. }
  27. r_heap & r_heap::operator = (const r_heap & rh) {
  28.   if (this != &rh) {
  29.     delete[] buckets;
  30.     delete[] u;
  31.     copy_heap(rh);
  32.   }
  33. }
  34. inline void r_heap::add_item(r_heap_item it, int bnr)
  35. {
  36.   it->succ = buckets[bnr];
  37.   if (buckets[bnr] != nil)
  38.     buckets[bnr]->pred = it;
  39.   it->pred = nil;
  40.   it->bucket = bnr;
  41.   buckets[bnr] = it;
  42. }
  43. inline void r_heap::rm_item(r_heap_item it)
  44. {
  45.   if (it->pred != nil)
  46.     (it->pred)->succ = it->succ;
  47.   else
  48.     buckets[it->bucket] = it->succ;
  49.   if (it->succ != nil)
  50.     (it->succ)->pred = it->pred;
  51. }
  52. void r_heap::copy_heap(const r_heap & rh)
  53. {
  54.   C = rh.C;
  55.   B = rh.B;
  56.   si = rh.si;
  57.   buckets = (r_heap_item *) new int[B];
  58.   u = new int[B];
  59.   bsize = new int[B];
  60.   for (int i = 0; i < B; i++) {
  61.     u[i] = rh.u[i];
  62.     bsize[i] = rh.bsize[i];
  63.   }
  64.   r_heap_item item1, item2;
  65.   for (i = 0; i < rh.B; i++) {
  66.     if (rh.buckets[i] != nil) {
  67.       item1 = rh.buckets[i];
  68.       do {
  69. item2 = new r_heap_node(item1->key, item1->inf);
  70. add_item(item2, i);
  71. item1 = item1->succ;
  72.       } while (item1 != nil);
  73.     }
  74.     else
  75.       buckets[i] = nil;
  76.   }
  77. }
  78. inline void r_heap::set_bucket_bounds(int min, int upto)
  79. {
  80.   u[0] = min;
  81.   for (int i = 1; i < upto; i++) {
  82.     u[i] = u[i - 1] + bsize[i];
  83.     if (u[i] > u[upto])
  84.       break;
  85.   }
  86.   for (; i < upto; i++)
  87.     u[i] = u[upto];
  88. }
  89. inline int r_heap::findbucket(r_heap_item it, int start)
  90. {
  91.   if (int (it->key) == u[0])
  92.     start = -1;
  93.   else
  94.     while (int (it->key) <= u[--start]);
  95. /* now $u[start] < int(it->key) le u[start+1]$ */
  96.   return (start + 1);
  97. }
  98. r_heap_item r_heap::find_min(void) const
  99. {
  100.   if (si > 0)
  101.     return buckets[0];
  102.   else
  103.     error_handler(1, "r_heap::find_min : Heap is empty!");
  104. }
  105. r_heap_item r_heap::insert(GenPtr k, GenPtr i)
  106. {
  107.   r_heap_item item = new r_heap_node(k, i);
  108.   if (si > 0) { /* We check whether the operation respects
  109.  * the r_heap conditions */
  110.     if (int (k) < u[0] || int (k) > u[0] + C) {
  111.       string s("r_heap::insert: k= %d out of range [%d,%d]n", int (k), u[0], u[0] + C);
  112.       error_handler(1, s);
  113.     }
  114.     int i = findbucket(item, B - 1);
  115.     add_item(item, i);
  116.   }
  117.   else {
  118.     set_bucket_bounds((int) k, B - 1);
  119.     buckets[0] = item;
  120.     item->bucket = 0;
  121.   }
  122.   si++;
  123.   return item;
  124. }
  125. void r_heap::del_min(void)
  126. {
  127.   if (si > 0) {
  128.     r_heap_item it = buckets[0];
  129.     del_item(it);
  130.   }
  131.   else
  132.     error_handler(1, "r_heap::del_min : Heap is empty!");
  133. }
  134. void r_heap::decrease_key(r_heap_node * x, GenPtr k)
  135. {
  136.   if ((int (k) < int (x->key)) &&(int (k) >= u[0])) {
  137.     x->key = k;
  138.     if ((int (k) <= u[x->bucket - 1])) {
  139.       rm_item(x);
  140.       int i = findbucket(x, x->bucket);
  141.       add_item(x, i);
  142.     }
  143.   }
  144.   else {
  145.     string s("r_heap::decrease_key: k= %d out of range [%d,%d]n", int (k), u[0], int (x->key) - 1);
  146.     error_handler(1, s);
  147.   }
  148. }
  149. void r_heap::change_inf(r_heap_node * x, GenPtr i)
  150. {
  151.   x->inf = i;
  152. }
  153. void r_heap::clear(void)
  154. {
  155.   r_heap_item it;
  156.   for (int i = 1; i < B; i++)
  157.     while ((it = buckets[i]) != nil) {
  158.       rm_item(it);
  159.       delete it;
  160.     }
  161. }
  162. void r_heap::del_item(r_heap_node * x)
  163. {
  164.   int buck = x->bucket;
  165.   rm_item(x);
  166.   delete x;
  167.   if ((si > 1) && (buck == 0) && (buckets[0] == nil)) {
  168.     r_heap_item item;
  169.     int idx = 1;
  170.     while (buckets[idx] == nil)
  171.       idx++;
  172.     item = buckets[idx];
  173.     r_heap_item dummy = item->succ;
  174.     while (dummy != nil) {
  175.       if ((int) dummy->key < (int) item->key)
  176. item = dummy;
  177.       dummy = dummy->succ;
  178.     }
  179. /* we have found the minimum */
  180.     set_bucket_bounds(int (item->key), idx);
  181.     rm_item(item);
  182.     add_item(item, 0);
  183. /* Redistribution */
  184.     item = buckets[idx];
  185.     r_heap_item next;
  186.     while (item != nil) {
  187.       next = item->succ;
  188. /* we know that every item in bucket #idx MUST be redistributed */
  189.       rm_item(item);
  190.       int i = findbucket(item, idx);
  191.       add_item(item, i);
  192.       item = next;
  193.     }
  194.   }
  195.   si--;
  196. }
  197. int r_heap::size(void) const
  198. {
  199.   return si;
  200. }
  201. int r_heap::empty(void) const
  202. {
  203.   return (si == 0);
  204. }
  205. r_heap_item r_heap::first_item(void) const
  206. {
  207.   return buckets[0]; /* nil if heap is empty */
  208. }
  209. r_heap_item r_heap::next_item(r_heap_item p) const
  210. {
  211.   if (p->succ != nil)
  212.     return p->succ;
  213.   else {
  214.     int next = p->bucket + 1;
  215.     while ((next < B) && (buckets[next] == nil))
  216.       next++;
  217.     if (next == B)
  218.       return nil;
  219.     else
  220.       return buckets[next];
  221.   }
  222. }
  223. void r_heap::print_contents(ostream & os) const
  224. {
  225.   r_heap_item item;
  226.   os << "--------------------------------------n";
  227.   os << "Si: " << si << "n";
  228.   os << "--------------------------------------n";
  229.   for (int i = 0; i < B; i++) {
  230.     os << "--------------------------------------n";
  231.     os << "Bucket " << i << "n";
  232.     os << "Intervall: [";
  233.     if (i > 0)
  234.       os << u[i - 1] - 1;
  235.     else
  236.       os << u[i];
  237.     os << "," << u[i] << "]n";
  238.     os << "--------------------------------------n";
  239.     item = buckets[i];
  240.     while (item != nil) {
  241.       os << "Key: " << (int) item->key << " Bucket: " << item->bucket;
  242.       os << "n";
  243.       item = item->succ;
  244.     }
  245.   }
  246. }