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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _olist.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/olist.h>
  12. #include <ctype.h>
  13. #define SWAP(a,b) { register obj_link* x = *a; *a = *b; *b = x; }
  14. #define MIN_D 16 
  15. //------------------------------------------------------------------------------
  16. // Members of class obj_list
  17. //------------------------------------------------------------------------------
  18. obj_list::obj_list()      
  19. { h = nil; 
  20.   t = nil;
  21.   count = 0;
  22. }
  23. void obj_list::clear()
  24. { h = nil;
  25.   t = nil;
  26.   count = 0;
  27.  }
  28. obj_link* obj_list::get_item(int i) const
  29. { obj_link* p = h;
  30.   while ( p && i--) p = p->succ_link; 
  31.   return p;
  32. }
  33. obj_link* obj_list::succ(obj_link* p, int i)  const
  34. { while ( p && i--) p = p->succ_link; 
  35.   return p;
  36. }
  37. obj_link* obj_list::pred(obj_link* p, int i) const
  38. { while ( p && i--) p = p->pred_link; 
  39.   return p;
  40. }
  41. int obj_list::rank(obj_link* x)   const   /* rank by linear search */
  42. { obj_link* p = h;
  43.   int r = 1;
  44.   while ( p && p != x) 
  45.   { p = p->succ_link; 
  46.     r++;
  47.    }
  48.   return (p) ? r : 0;
  49. obj_link* obj_list::insert(obj_link* n, obj_link* l, int dir) 
  50.   if (dir==0) //insert after l
  51.     return insert(n,l);
  52.   else //insert before l
  53.     { obj_link* p=l->pred_link;
  54.       n->pred_link = p;
  55.       n->succ_link = l;
  56.       l->pred_link = n;
  57.       if (l==h) h=n;
  58.       else p->succ_link = n;
  59.       count++;
  60.       return n;
  61.     }
  62. }
  63. void obj_list::conc(obj_list& l)
  64. { if (t) { t->succ_link = l.h;
  65.           if (l.h) { l.h->pred_link = t; t = l.t; } }
  66.    else { h = l.h; t = l.t; }
  67.  count = count+l.count;
  68.  l.h = l.t = 0;
  69.  l.count = 0;
  70. }
  71. void obj_list::split(obj_link* p, obj_list& l1, obj_list& l2)
  72.   l1.clear();
  73.   l2.clear();
  74.   if (p==nil)    // l1 = empty,  l2 = l, l = empty;
  75.   { l2.h = h;
  76.     l2.t = t;
  77.     l2.count = count;
  78.     h = t = 0;
  79.     count = 0;
  80.     return;
  81.    }
  82.   if (h == 0) return;   /* empty list */
  83.   if (p->pred_link)
  84.   { l1.h = h;
  85.     l1.t = p->pred_link;
  86.     p->pred_link->succ_link = 0;
  87.    }
  88.   p->pred_link = 0;
  89.   l2.h = p;
  90.   l2.t = t;
  91.   // have to set counters
  92.   // "count the smaller half" gives amortized n log n  bound
  93.   obj_link* l = l1.h;
  94.   obj_link* r = l2.h;
  95.   int    c = 0;
  96.   while (l && r)
  97.   { l = l->succ_link;
  98.     r = r->succ_link;
  99.     c++;
  100.    }
  101.   if (l==0)   // left end reached first
  102.   { l1.count = c;
  103.     l2.count = count - l1.count;
  104.    }
  105.   else
  106.   { l2.count = c;
  107.     l1.count = count - l2.count;
  108.    }
  109.   /* make original list empty */
  110.   
  111.   h = t = 0;
  112.   count = 0;
  113. }
  114. void obj_list::del(obj_link* x)
  115.   if (x==h)  
  116.     pop();
  117.   else
  118.     if (x==t)  
  119.        Pop();
  120.     else
  121.        { obj_link*  p = x->pred_link;
  122.          obj_link*  s = x->succ_link;
  123.          p->succ_link = s;
  124.          s->pred_link = p;
  125.          count--;
  126.         }
  127. }
  128. obj_link* obj_list::max(CMP_ITEM f) const
  129. { if (h==0) return 0;
  130.   obj_link* m=h;
  131.   obj_link* p=m->succ_link;
  132.      while (p)
  133.      { if (f(p,m) > 0) m=p;
  134.        p=p->succ_link;
  135.       }
  136.   return m;
  137. }
  138. obj_link* obj_list::min(CMP_ITEM f) const
  139. { if (h==0) return 0;
  140.   obj_link* m=h;
  141.   obj_link* p=m->succ_link;
  142.      while (p)
  143.      { if (f(p,m) < 0) m=p;
  144.        p=p->succ_link;
  145.      }
  146.   return m;
  147. }
  148. void obj_list::apply(APP_ITEM apply)
  149. { register obj_link* p = h;
  150.   while (p)
  151.   { apply(p);
  152.     p = p->succ_link;
  153.    }
  154. }
  155. void obj_list::permute()
  156.   obj_link** A = new obj_link*[count+2];
  157.   obj_link* x = h;
  158.   int j;
  159.   A[0] = A[count+1] = 0;
  160.  
  161.   for(j=1; j <= count; j++)
  162.   { A[j] = x;
  163.     x = x->succ_link;
  164.    }
  165.   for(j=1; j<count; j++)  
  166.   { int r = rand_int(j,count);
  167.     x = A[j];
  168.     A[j] = A[r];
  169.     A[r] = x;
  170.    }
  171.   for(j=1; j<=count; j++) 
  172.   { A[j]->succ_link = A[j+1];
  173.     A[j]->pred_link = A[j-1];
  174.    }
  175.   h = A[1];
  176.   t = A[count];
  177.   
  178.   delete A;
  179. }
  180.         
  181. void obj_list::bucket_sort(int i, int j, ORD_ITEM ord)
  182.   int n = j-i+1;
  183.   register obj_link** bucket= new obj_link*[n+1];
  184.   register obj_link** stop = bucket + n;
  185.   register obj_link** p;
  186.   register obj_link* q;
  187.   register obj_link* x;
  188.   for(p=bucket;p<=stop;p++)  *p = 0;
  189.   while (h) 
  190.   { x = h; 
  191.     h = h->succ_link;
  192.     int k = ord(x);
  193.     if (k >= i && k <= j) 
  194.      { p = bucket+k-i;
  195.        x->succ_link = *p;
  196.        if (*p) (*p)->pred_link = x;
  197.        *p = x;
  198.       }
  199.     else 
  200.        error_handler(4,"bucket_sort: value out of range") ;
  201.    }
  202.  for(p=bucket; *p==0 && p<stop; p++);
  203.   
  204.  h = *p;
  205.  if (h) 
  206.  { for(q=h;q->succ_link; q = q->succ_link);
  207.    h->pred_link = 0;
  208.    p++;
  209.   }
  210.  while(p<stop) 
  211.  { if (*p)
  212.    { q->succ_link = *p;
  213.      (*p)->pred_link = q;
  214.      while(q->succ_link) q = q->succ_link;
  215.     }
  216.    p++;
  217.   }
  218.  t = q;
  219.  delete bucket;
  220. }
  221.         
  222. void obj_list::quick_sort(obj_link** l, obj_link** r, CMP_ITEM usr_cmp)
  223. { // use parameter usr_cmp
  224.   register obj_link** i = l+(r-l)/2; //rand_int()%(r-l);
  225.   register obj_link** k;
  226.  
  227.   if (usr_cmp((*i),(*r))>0) SWAP(i,r);
  228.   SWAP(l,i);
  229.  
  230.   obj_link* s = (*l);
  231.  
  232.   i = l;
  233.   k = r;
  234.   for(;;)
  235.   { while (usr_cmp((*(++i)),s)<0);
  236.     while (usr_cmp((*(--k)),s)>0);
  237.     if (i<k) SWAP(i,k) else break;
  238.    }
  239.   SWAP(l,k);
  240.   if (k > l+MIN_D) quick_sort(l,k-1,usr_cmp);
  241.   if (r > k+MIN_D) quick_sort(k+1,r,usr_cmp);
  242. }
  243.         
  244. void obj_list::insertion_sort(obj_link** l, obj_link** r, obj_link** min_stop, 
  245.                                CMP_ITEM usr_cmp)
  246. {
  247.   register obj_link** min=l;
  248.   register obj_link** run;
  249.   register obj_link** p;
  250.   register obj_link** q;
  251.   for (run = l+1; run <= min_stop; run++)
  252.       if (usr_cmp((*run),(*min)) < 0) min = run;
  253.   SWAP(min,l);
  254.   if (r == l+1) return; 
  255.   for(run=l+2; run <= r; run++)
  256.   { for (min = run-1; usr_cmp((*run),(*min)) < 0; min--);
  257.     min++;
  258.     if (run != min) 
  259.     { obj_link* save = *run;
  260.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  261.       *min = save;
  262.      }
  263.    }
  264. }
  265. void obj_list::sort(CMP_ITEM f)
  266.   if (count<=1) return;    // nothing to sort
  267.   obj_link** A = new obj_link*[count+2];
  268.   register obj_link*  loc = h;
  269.   register obj_link** p;
  270.   register obj_link** stop = A+count+1;
  271.   obj_link** left  = A+1;
  272.   obj_link** right = A+count;
  273.   obj_link** min_stop = left + MIN_D;
  274.   if (min_stop > right) min_stop = right;
  275. min_stop = right;
  276.   for(p=A+1; p<stop; p++)
  277.   { *p = loc;
  278.     loc = loc->succ_link;
  279.    }
  280.    quick_sort(left,right,f);
  281.    insertion_sort(left,right,min_stop,f);
  282.   *A = *stop = 0;
  283.   for (p=A+1;p<stop;p++) 
  284.   { (*p)->succ_link = *(p+1);
  285.     (*p)->pred_link = *(p-1);
  286.    }
  287.   h = A[1];
  288.   t = A[count];
  289.   delete A;
  290. }