_r_heap.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:6k
开发平台:

MultiPlatform

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