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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _skiplist.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. //------------------------------------------------------------------------------
  12. //
  13. //  skip lists 
  14. //
  15. //  doubly linked
  16. //
  17. //  S. Naeher (1992)
  18. //
  19. //------------------------------------------------------------------------------
  20.  
  21. #include <LEDA/impl/skiplist.h>
  22. #define NODE_SIZE(l) sizeof(skiplist_node)+l*sizeof(skiplist_node*)
  23.  
  24. #define NEW_NODE(p,l) p=(skiplist_item)allocate_bytes(NODE_SIZE(l));p->level=l;
  25. #define NEW_NODE_0(p,l) p=(skiplist_item)malloc(NODE_SIZE(l));p->level=l;
  26. #define FREE_NODE(p) deallocate_bytes(p,NODE_SIZE(p->level))
  27. #define FREE_NODE_0(p) free((char*)p)
  28. unsigned long skiplist_node::id_count = 0;
  29.  
  30. const int BitsInRandom      = 31;
  31. const int MaxNumberOfLevels = 32;
  32.  
  33. skiplist::skiplist(float p) 
  34. { prob = p;
  35.   randomBits = ran.get();
  36.   randomsLeft = BitsInRandom;
  37.   level = 0;
  38.   count = 0;
  39.   NEW_NODE_0(header,MaxNumberOfLevels);
  40.   NEW_NODE_0(STOP,-1);
  41.   STOP->backward = header;
  42.   STOP->pred = header;
  43.   for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  44.   header->backward = 0;
  45.   header->pred = 0;
  46.  } 
  47.  
  48. skiplist::skiplist(const skiplist& L) 
  49. { prob = L.prob;
  50.   randomBits = ran.get();
  51.   randomsLeft = BitsInRandom;
  52.   level = 0;
  53.   count = 0;
  54.   NEW_NODE_0(header,MaxNumberOfLevels);
  55.   NEW_NODE_0(STOP,-1);
  56.   STOP->backward = header;
  57.   STOP->pred = header;
  58.   for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  59.   header->backward = 0;
  60.   header->pred = 0;
  61.  
  62.   skiplist_item p = L.STOP->pred;
  63.   while (p!= L.header) 
  64.   { insert_at_item(header,p->key,p->inf);
  65.     L.copy_key(p->key);
  66.     L.copy_inf(p->inf);
  67.     p = p->pred;
  68.    }
  69.  } 
  70.  
  71.  
  72. skiplist& skiplist::operator=(const skiplist& L) 
  73. { clear();
  74.   skiplist_item p = L.STOP->pred;
  75.   while (p!= L.header) 
  76.   { insert_at_item(header,p->key,p->inf);
  77.     p = p->pred;
  78.    }
  79.   return *this;
  80.  } 
  81.  
  82. void skiplist::clear() 
  83. { register skiplist_item p,q;
  84.   p = header->forward[0];
  85.   while(p!=STOP)
  86.   { q = p->forward[0];
  87.     clear_key(p->key);
  88.     clear_inf(p->inf);
  89.     FREE_NODE(p);
  90.     p = q; 
  91.    }
  92.  level = 0;
  93.  for(int i=0;i<MaxNumberOfLevels;i++) header->forward[i] = STOP;
  94.  STOP->pred = header;
  95.  count = 0;
  96. }
  97.  
  98.  
  99.  
  100. skiplist::~skiplist() 
  101. { clear();
  102.   FREE_NODE_0(header);
  103.   FREE_NODE_0(STOP);
  104.  }
  105.  
  106.  
  107. int skiplist::randomLevel()
  108. { register int lev = 0;
  109.   register unsigned long b = 0;
  110.    while (b==0)
  111.    { b = randomBits&3;    // read next two random bits
  112.      randomBits >>= 2;
  113.      randomsLeft -= 2;
  114.      if (b==0) lev++;   // increase level with prob 0.25
  115.      if (randomsLeft < 2) 
  116.      { randomBits = ran.get();
  117.        randomsLeft = BitsInRandom;
  118.       }
  119.     }
  120. /*
  121.     // user defined probability "prob"
  122.     { float r;
  123.       ran >> r;
  124.       while (r < prob)
  125.       { lev++;
  126.         ran >> r;
  127.        }
  128.      }
  129. */
  130.     
  131.    return lev;
  132.  }
  133.  
  134.  
  135. skiplist_item skiplist::search(GenPtr key, int& l) const
  136. { register skiplist_item p = header;
  137.   register skiplist_item q;
  138.   register int k;
  139.   register int c=1;
  140.  
  141.   if (int_type())
  142.   { STOP->key = key;
  143.     for(k = level; k>=0; k--)
  144.     { q = p->forward[k];
  145.       while (LEDA_ACCESS(int,key) > LEDA_ACCESS(int,q->key)) 
  146.       { p = q;
  147.         q = p->forward[k];
  148.        }
  149.       if(key==q->key && q != STOP) break;
  150.      }
  151.    }
  152.   else
  153.   { for(k = level; k>=0; k--)
  154.     { q = p->forward[k];
  155.       while (k==q->level && (c=cmp(key,q->key)) > 0)
  156.       { p = q;
  157.         q = p->forward[k];
  158.        }
  159.       if(c==0) break;
  160.      }
  161.    }
  162.   l = k;
  163.   return q;
  164.  }
  165.  
  166. skiplist_item skiplist::locate(GenPtr key) const { return locate_succ(key); }
  167. skiplist_item skiplist::locate_succ(GenPtr key) const
  168. { int k;
  169.   skiplist_item q = search(key,k);
  170.   return (q==STOP) ? 0 : q;
  171.  }
  172. skiplist_item skiplist::locate_pred(GenPtr key) const
  173. { int k;
  174.   skiplist_item q = search(key,k);
  175.   if (q==STOP) return max();
  176.   if (cmp(key,q->key)!=0) q = q->pred;
  177.   return (q==header) ? 0 : q;
  178.  }
  179.  
  180. skiplist_item skiplist::lookup(GenPtr key) const
  181. { int k;
  182.   skiplist_item q = search(key,k);
  183.   return (k<0) ? 0 : q;
  184.  }
  185. void skiplist::insert_item_at_item(skiplist_item q, skiplist_item p)
  186.   // insert item q immediately after item p
  187.   register skiplist_item x;
  188.   register int k;
  189.   q->pred = p;
  190.   p->forward[0]->pred = q;
  191.   for(k=0; k<=q->level; k++)
  192.   { while (k > p->level) p = p->backward;
  193.     x = p->forward[k];
  194.     q->forward[k] = x;
  195.     p->forward[k] = q;
  196.     if (x->level == k) x->backward = q;
  197.    }
  198.    q->backward = p;
  199.  }
  200.  
  201. skiplist_item skiplist::insert_at_item(skiplist_item p, GenPtr key, GenPtr inf)
  202. { register skiplist_item q;
  203.   register int k;
  204.   if (p != header)
  205.   { int c = cmp(key,p->key);
  206.     if (c == 0)
  207.     { clear_inf(p->inf);
  208.       copy_inf(inf);
  209.       p->inf = inf;
  210.       return p;
  211.      }
  212.     if (c<0) p = p->pred;
  213. /*
  214.      if (p!=min() && cmp(key,p->pred->key) <= 0)
  215.      {  cout << "wrong position for "; print_key(key);
  216.         newline;
  217.         cout << " pos = "; print_key(p->key);
  218.         newline;
  219.         cout << " pred = "; print_key(p->pred->key);
  220.         newline;
  221.         error_handler(1,"skiplist::insert_at : wrong position "); 
  222.       }
  223. */
  224.    }
  225.  
  226.    k = randomLevel();
  227.    if (k>level) k = ++level;
  228.  
  229.    NEW_NODE(q,k);
  230.    copy_key(key);
  231.    copy_inf(inf);
  232.    q->key = key;
  233.    q->inf = inf;
  234.    q->id = skiplist_node::id_count++;
  235.    count++;
  236.    insert_item_at_item(q,p);
  237.  
  238.    return q;
  239.  }
  240. void skiplist::remove_item(skiplist_item q)
  241. { register int k;
  242.   register skiplist_item p = q->backward;
  243.   register skiplist_item x;
  244.   for(k=q->level; k>=0; k--)
  245.   { while (p->forward[k] != q) p = p->forward[k];
  246.     x = q->forward[k];
  247.     p->forward[k] = x;
  248.     if (x->level==k) x->backward = p;
  249.    }
  250.   x->pred = p;
  251. }
  252.  
  253.  
  254. void skiplist::del_item(skiplist_item q)
  255. { remove_item(q);
  256.   clear_key(q->key);
  257.   clear_inf(q->inf);
  258.   FREE_NODE(q);
  259.   while(header->forward[level] == STOP && level > 0 ) level--;
  260.   count --;
  261. }
  262. skiplist_item skiplist::insert(GenPtr key, GenPtr inf)
  263. { int k;
  264.   skiplist_item p = search(key,k);
  265.   if (p==STOP) p = p->pred;
  266.   return insert_at_item(p,key,inf);
  267.  }
  268. void skiplist::del(GenPtr key)
  269. { int k;
  270.   skiplist_item q = search(key,k);
  271.   if (k>=0) del_item(q);
  272.  }
  273. void skiplist::reverse_items(skiplist_item p, skiplist_item q)
  274. { skiplist_item r;
  275.   while (p!=q)
  276.   { r = p;
  277.     p = p->forward[0];
  278.     remove_item(r);
  279.     insert_item_at_item(r,q);
  280.    }
  281.  }
  282. void skiplist::conc(skiplist&)
  283. { error_handler(1,"sorry, not implemented: skiplist::conc(skiplist)n"); }
  284. void skiplist::split_at_item(skiplist_item,skiplist&,skiplist&)
  285. { error_handler(1,"sorry, not implemented: skiplist::split_at_itemn"); }
  286. void skiplist::print()
  287. { skiplist_item p = header;
  288.   cout << "Level = " << level << "n"; 
  289.   for(;;)
  290.   { cout << string("<%d>  ",p);
  291.     if (p != header && p != STOP)
  292.     { cout << "key = ";
  293.       print_key(p->key);
  294.      }
  295.     newline;
  296.     for(int k=p->level;k>=0;k--)
  297.        cout << string("forward[%d] = %8dn", k,p->forward[k]);
  298.     cout << string("backward = %8d   pred = %8dn",p->backward, p->pred);
  299.     if (p==STOP) break;
  300.     p = p->forward[0];
  301.     newline;
  302.    }
  303. }