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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _bin_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/bin_heap.h>
  12. //------------------------------------------------------------------------------
  13. // bin_heap: binary heaps  
  14. //           (compressed representation with array doubling)
  15. //
  16. // S. Naeher (1993)
  17. //
  18. //------------------------------------------------------------------------------
  19. #define KEY(i)   (HEAP[i]->key)
  20. #define INF(i)   (HEAP[i]->inf)
  21. #define INTEGER(p)  LEDA_ACCESS(int,p)
  22. bin_heap::bin_heap(int n)  
  23. { if (n <= 0) 
  24.      error_handler(1,string("bin_heap constructor: illegal size = %d",n));
  25.   HEAP = new bin_heap_item[n];
  26.   for(int i = 0; i < n; i++) HEAP[i] = nil;
  27.   count = 0; 
  28.   max_size = n-2;  // sometimes we use HEAP[0], HEAP[count+1] as stoppers
  29. }
  30. bin_heap::bin_heap(const bin_heap& H)
  31. { max_size = H.max_size;
  32.   count = H.count; 
  33.   HEAP = new bin_heap_item[max_size+2];
  34.   for(int i = 1; i <= count; i++) 
  35.   { HEAP[i] = new bin_heap_elem(H.HEAP[i]->key, H.HEAP[i]->inf,i);
  36.     H.copy_key(HEAP[i]->key);
  37.     H.copy_inf(HEAP[i]->inf);
  38.   }
  39. }
  40. bin_heap& bin_heap::operator=(const bin_heap& H)
  41. { clear();
  42.   delete[] HEAP;
  43.   max_size = H.max_size;
  44.   count = H.count; 
  45.   HEAP = new bin_heap_item[max_size+2];
  46.   for(int i = 1; i <= count; i++) 
  47.   { HEAP[i] = new bin_heap_elem(H.HEAP[i]->key, H.HEAP[i]->inf,i);
  48.     copy_key(HEAP[i]->key);
  49.     copy_inf(HEAP[i]->inf);
  50.   }
  51.   return *this;
  52. }
  53. bin_heap::~bin_heap()  
  54. { clear();
  55.   delete[] HEAP; 
  56. }
  57. void bin_heap::clear()
  58. { for(int i=1; i <= count; i++) 
  59.   { clear_key(KEY(i));
  60.     clear_inf(INF(i));
  61.     delete HEAP[i];
  62.    }
  63.   count = 0;
  64. }
  65. void bin_heap::rise(int pos, bin_heap_item it)
  66.   HEAP[0] = it;  // use "it" as stopper
  67.   register int  pi = pos/2;                     // parent index
  68.   register bin_heap_item parent = HEAP[pi];     // parent node
  69.   if (int_type())
  70.    { int k0 = INTEGER(it->key);
  71.      while(INTEGER(parent->key) > k0)
  72.      { HEAP[pos] = parent;
  73.        parent->index = pos;
  74.        pos = pi;
  75.        pi >>= 1;
  76.        parent = HEAP[pi];
  77.       }
  78.     }
  79.   else
  80.      while (cmp(parent->key,it->key) > 0)
  81.      { HEAP[pos] = parent;
  82.        parent->index = pos;
  83.        pos = pi;
  84.        pi >>= 1;
  85.        parent = HEAP[pi];
  86.       }
  87.   HEAP[pos] = it;
  88.   it->index = pos;
  89. }
  90. void bin_heap::sink(int pos, bin_heap_item it)
  91.   register int ci = 2*pos;       // child index
  92.   register bin_heap_item child;  // child node
  93.   HEAP[count+1] = HEAP[count];   // stopper
  94.   if (int_type())
  95.    { int k0 = INTEGER(it->key);
  96.      while (ci <= count)
  97.      { child = HEAP[ci];
  98.        if (INTEGER(KEY(ci+1)) < INTEGER(child->key)) child = HEAP[++ci];
  99.        if (k0 > INTEGER(child->key)) 
  100.        { HEAP[pos] = child;
  101.          child->index = pos;
  102.          pos = ci;
  103.          ci <<= 1;
  104.         }
  105.        else break;
  106.       }
  107.     }
  108.   else
  109.      while (ci <= count)
  110.      { child = HEAP[ci];
  111.        if (ci < count && cmp(KEY(ci+1),child->key) < 0) child = HEAP[++ci];
  112.        if (cmp(it->key,child->key)>0) 
  113.        { HEAP[pos] = child;
  114.          child->index = pos;
  115.          pos = ci;
  116.          ci <<= 1;
  117.         }
  118.        else break;
  119.       }
  120.   HEAP[pos] =it;
  121.   it->index = pos;
  122. }
  123. void bin_heap::decrease_key(bin_heap_item it, GenPtr k)
  124. { if (cmp(it->key,k)<0) 
  125.        error_handler(1,"bin_heap: key too large in decrease_key");
  126.   clear_key(it->key);
  127.   copy_key(k);
  128.   it->key = k;
  129.   rise(it->index, it);
  130. }
  131. bin_heap_item bin_heap::insert(GenPtr k, GenPtr i) 
  132.   bin_heap_item* H;
  133.   if (count == max_size)  // resize
  134.   { // max_size *= 2;     // double array
  135.     max_size += 1024;
  136.     H = new bin_heap_item[max_size+2];
  137.     for(int i=1; i<= count; i++) H[i] = HEAP[i];
  138.     delete[] HEAP;
  139.     HEAP = H;
  140.    }
  141.   count++;
  142.   copy_key(k);
  143.   copy_inf(i);
  144.   bin_heap_item it = new bin_heap_elem(k,i,count);
  145.   rise(count,it);
  146.   return it;
  147. }
  148. void bin_heap::del_item(bin_heap_item it)
  149. { bin_heap_item p = HEAP[count];
  150.   HEAP[count] = nil;
  151.   count--;
  152.   if (it != p)
  153.   { if (cmp(p->key,it->key) > 0)
  154.        sink(it->index, p);
  155.     else
  156.        rise(it->index, p);
  157.    }
  158.   clear_key(it->key);
  159.   clear_inf(it->inf);
  160.   delete it;
  161. }
  162. void bin_heap::change_inf(bin_heap_item it, GenPtr i) 
  163. { clear_inf(it->inf);
  164.   copy_inf(i);
  165.   it->inf = i; 
  166.  }
  167. void bin_heap::print()
  168. { cout << "size = " << count << endl;
  169.   for(int i=1;i<=count;i++) 
  170.   { print_key(KEY(i));
  171.     cout << "-";
  172.     print_inf(INF(i));
  173.     cout << "  ";
  174.    }
  175.   newline;
  176. }