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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _ch_map.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/ch_map.h>
  12. //------------------------------------------------------------------------------
  13. //
  14. //  hashing array with chaining and table doubling
  15. //
  16. //  only integer/pointer keys
  17. //  no delete operation
  18. //
  19. //  S. Naeher (1994)
  20. //
  21. //------------------------------------------------------------------------------
  22. #define NIL 0xFFFFFFFF
  23. ch_map_elem ch_map::STOP;
  24. ch_map::ch_map(int sz, int n) 
  25.   shift = 0;
  26.   while (sz >>= 1) shift++;
  27.   if (n < 512)
  28.      init_table(512); 
  29.   else
  30.    { int ts = 1;
  31.      while (ts < n) ts <<= 1;
  32.      init_table(ts);
  33.     }
  34. }
  35. GenPtr ch_map::lookup(unsigned long x) const
  36. { ch_map_item p = HASH(x);
  37.   STOP.k = x;
  38.   while (p->k != x) p = p->succ;
  39.   return (p == &STOP) ? nil : p;
  40. }
  41. GenPtr ch_map::access(unsigned long x) const
  42. { ch_map_item p = HASH(x);
  43.   GenPtr y;
  44.   STOP.k = x;
  45.   while (p->k != x) p = p->succ;
  46.   if (p == &STOP) init_inf(y);
  47.   else y = p->i;
  48.   return y;
  49. }
  50. GenPtr& ch_map::access1(ch_map_item p, unsigned long x)
  51.   STOP.k = x;
  52.   ch_map_item q = p->succ; 
  53.   while (q->k != x) q = q->succ;
  54.   if (q != &STOP) return q->i;
  55.   // index x not present, insert it
  56.   if (free == table_end)   // table full: rehash
  57.   { rehash();
  58.     p = HASH(x);
  59.    }
  60.   if (p->k == nil)
  61.   { p->k = x;
  62.     init_inf(p->i);
  63.     return p->i;
  64.    }
  65.   q = free++;
  66.   q->k = x;
  67.   init_inf(q->i);
  68.   q->succ = p->succ;
  69.   p->succ = q;
  70.   return q->i;
  71. }
  72. void ch_map::clear_entries() 
  73. { for(ch_map_item p = table; p < free; p++)
  74.     if (p->k != NIL) clear_inf(p->i);
  75.  }
  76. void ch_map::init_table(int T)
  77.   table_size = T;
  78.   table_size_1 = T-1;
  79.   table = new ch_map_elem[2*T];
  80.   free = table + T;
  81.   table_end = free + T/2;
  82.   for (ch_map_item p=table; p < free; p++) 
  83.   { p->k = NIL;
  84.     p->succ = &STOP;
  85.    }
  86. }
  87. #define INSERT(x,y)
  88. { ch_map_item q = HASH(x);
  89.   if (q->k == NIL)
  90.     { q->k = x;
  91.       q->i = y;
  92.      }
  93.   else
  94.    { free->k = x;
  95.      free->i = y;
  96.      free->succ = q->succ;
  97.      q->succ = free++;
  98.    }
  99. }
  100. void ch_map::rehash()
  101.   ch_map_item old_table = table;
  102.   ch_map_item old_table_mid = table+table_size;
  103.   ch_map_item old_table_end = table_end;
  104.   
  105.   //init_table(2*table_size);
  106.   init_table(4*table_size);
  107.   ch_map_item p;
  108.   for(p = old_table; p < old_table_mid; p++)
  109.   { unsigned long x = p->k;
  110.     if (x != NIL)
  111.     { ch_map_item q = HASH(x);
  112.       q->k = x;
  113.       q->i = p->i;
  114.      }
  115.    }
  116.   while (p < old_table_end)
  117.   { unsigned long x = p->k;
  118.     INSERT(x,p->i);
  119.     p++;
  120.    }
  121.   delete[] old_table;
  122. }
  123. void ch_map::start_iteration()
  124. { iterator = table;
  125.   while (iterator < table_end && iterator->k == NIL) iterator++;
  126.  }
  127. bool ch_map::next_index(unsigned long& p)
  128. { if (iterator == table_end) return false;
  129.   p = iterator->k;
  130.   iterator++;
  131.   while (iterator < table_end && iterator->k == NIL) iterator++;
  132.   return true;
  133.  }
  134. ch_map::ch_map(const ch_map& D)
  135.   init_table(D.table_size);
  136.   for(ch_map_item p = D.table; p < D.table_end; p++) 
  137.   { if (p->k != NIL)
  138.     { INSERT(p->k,p->i);
  139.       D.copy_inf(p->i);
  140.      }
  141.    }
  142. }
  143. ch_map& ch_map::operator=(const ch_map& D)
  144.   clear_entries();
  145.   delete[] table;
  146.   init_table(D.table_size);
  147.   for(ch_map_item p = D.table; p < D.table_end; p++) 
  148.   { if (p->k != NIL)
  149.     { INSERT(p->k,p->i);
  150.       copy_inf(p->i);
  151.      }
  152.    }
  153.   return *this;
  154. }
  155. void ch_map::print()
  156. { cout << "shift = " << shift << endl;
  157.   for (int i=0; i<table_size; i++)
  158.   { ch_map_item p = table + i;
  159.     if (p->k != NIL)
  160.     { int l = 0;
  161.       while(p != &STOP)
  162.       { l++; 
  163.         p = p->succ;
  164.        }
  165.       cout << string("L(%d) = %d",i,l) << endl;
  166.      }
  167.    }
  168. }
  169.