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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _dlist.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/dlist.h>
  12. #include <ctype.h>
  13. #define SWAP(a,b) { register dlink* x = *a; *a = *b; *b = x; }
  14. #define MIN_D 16 
  15. //------------------------------------------------------------------------------
  16. // Members of class dlist: base class for all lists
  17. //------------------------------------------------------------------------------
  18. dlist::dlist()      
  19. { h=0; 
  20.   t=0;
  21.   count=0;
  22.   iterator=0; 
  23. }
  24. dlist::dlist(GenPtr a) 
  25. { h=t=new dlink(a,0,0);
  26.   count=1; 
  27.   iterator=0;  
  28. }
  29. dlist::dlist(const dlist& x)
  30. { register dlink* p;
  31.   iterator=h=t=0; 
  32.   count = 0; 
  33.                               
  34.   for (p = x.h; p; p = p->succ) append(p->e); 
  35.   if (!int_type())
  36.     for (p = h; p; p = p->succ) x.copy_el(p->e);
  37. }
  38. void dlist::recompute_length() const
  39. { int n = 0;
  40.   for(dlink* it = h; it; it = it->succ)  n++;
  41.   *(int*)&count = n;
  42. }
  43. //------------------------------------------------------------------------------
  44. // Iteration:
  45. //------------------------------------------------------------------------------
  46. dlink* dlist::move_iterator(int dir) const 
  47. { if (iterator) 
  48.      set_iterator(dir ? iterator->pred : iterator->succ);
  49.   else 
  50.      set_iterator(dir ? t : h);
  51.   return iterator;
  52.  } 
  53. bool dlist::current_element(GenPtr& x) const 
  54. { if (iterator) 
  55.   { x = iterator->e; 
  56.     return true; 
  57.    } 
  58.   return false; 
  59.  }
  60. bool dlist::next_element(GenPtr& x)    const 
  61. { if (iterator) 
  62.      set_iterator(iterator->succ);
  63.   else 
  64.      set_iterator(h);
  65.   if (iterator) 
  66.   { x = iterator->e;
  67.     return true; 
  68.    } 
  69.   return false; 
  70.  }
  71. bool dlist::prev_element(GenPtr& x)  const
  72. { if (iterator) 
  73.      set_iterator(iterator->pred);
  74.   else 
  75.      set_iterator(t);
  76.   if (iterator) 
  77.   { x = iterator->e;
  78.     return true; 
  79.    } 
  80.   return false; 
  81.  }
  82. //------------------------------------------------------------------------------
  83. dlink* dlist::get_item(int i) const
  84. { dlink* p = h;
  85.   while ( p && i--) p = p->succ; 
  86.   return p;
  87. }
  88. dlink* dlist::succ(dlink* p, int i)  const
  89. { while ( p && i--) p = p->succ; 
  90.   return p;
  91. }
  92. dlink* dlist::pred(dlink* p, int i) const
  93. { while ( p && i--) p = p->pred; 
  94.   return p;
  95. }
  96. dlink* dlist::search(GenPtr x) const  /* linear search */
  97. { dlink* p = h;
  98.   while ( p && cmp(p->e,x) != 0) p = p->succ; 
  99.   return p;
  100. int dlist::rank(GenPtr x)   const   /* rank by linear search */
  101. { dlink* p = h;
  102.   int r = 1;
  103.   while ( p && cmp(p->e,x) != 0)
  104.   { p = p->succ; 
  105.     r++;
  106.    }
  107.   return (p) ? r : 0;
  108. GenPtr dlist::pop()    
  109. { if (h==nil) return nil;
  110.   if (iterator!=0) error_handler(1,"pop: deletion while iterator is active");
  111.   dlink* x=h; 
  112.   h = h->succ;
  113.   if (h) h->pred = 0;
  114.   else t = nil;
  115.   GenPtr p = x->e;
  116.   delete x;
  117.   count--;
  118.   return p;
  119. }
  120. GenPtr dlist::Pop()    
  121. { if (h==nil) return 0;
  122.   if (iterator!=0) error_handler(1,"Pop: deletion while iterator is active");
  123.   dlink* x=t; 
  124.   t = t->pred;
  125.   if (t) t->succ = 0;
  126.   else h = nil;
  127.   GenPtr p = x->e;
  128.   delete x;
  129.   count--;
  130.   return p;
  131. }
  132. dlink* dlist::insert(GenPtr a, dlink* l, int dir) 
  133.   if (iterator!=0) error_handler(2,"insert: insertion while iterator is active");
  134.   if (l==0) return dir ? append(a) : push(a); 
  135.   dlink* s=l->succ;
  136.   dlink* p=l->pred;
  137.   dlink* n;
  138.   
  139.   if (dir==0) //insert after l
  140.   { n= new dlink(a,l,s);
  141.     l->succ = n;
  142.     if (l==t) t=n;
  143.     else s->pred = n;}
  144.   else //insert before l
  145.   { n= new dlink(a,p,l);
  146.     l->pred = n;
  147.     if (l==h) h=n;
  148.     else p->succ = n;}
  149.   if (count >= 0) count++;
  150.  
  151.   return n;
  152. }
  153. void dlist::conc(dlist& l, int dir)
  154.   if (iterator!=0) error_handler(2,"conc: iterator is active");
  155.   if (h==nil)
  156.    { h = l.h; 
  157.      t = l.t; 
  158.     }
  159.   else
  160.   { if (dir==0)  // append l 
  161.     { t->succ = l.h;
  162.       if (l.h) { l.h->pred = t; t = l.t; } 
  163.      }
  164.     else // prepend l
  165.     { h->pred = l.t;
  166.       if (l.t) { l.t->succ= h; h = l.h; } 
  167.      }
  168.    }
  169.  if (count < 0 || l.count < 0)
  170.     count = -1;
  171.  else
  172.     count += l.count;
  173.  l.h = l.t = 0;
  174.  l.count = 0;
  175. }
  176. void dlist::split(dlink* p, dlist& L1, dlist& L2, int dir)
  177.   // split L0 at item p into L1 and L2 and  L is made empty
  178.   // if p == nil copy L0 to L2 and make L1 empty (if not identical to L0)
  179.   // if p != nil we have to distinguish two cases
  180.   // dir == 0: p becomes first item of L2
  181.   // dir != 0: p becomes last item of L1
  182.   if (iterator) error_handler(1,"dlist::split: iterator is active.");
  183.   if (h == nil) error_handler(1,"dlist::split: list is empty.");
  184.   if (&L1 == &L2) error_handler(1,"dlist::split: identical arguments.");
  185.   if (this != &L1) L1.clear();
  186.   if (this != &L2) L2.clear();
  187.   if (p == nil) 
  188.   { p = h;
  189.     dir = 0;
  190.    }
  191.  /* The first item of L1 is either h or nil depending whether L1 is non-empty
  192.   * or not. L1 is empty if dir == 0 and p->pred does not exist. A similar 
  193.   * argument applies to L2. 
  194.   */
  195.   dlink* L1_last  = (dir != 0) ? p : p->pred;
  196.   dlink* L1_first = (L1_last)  ? h : nil;
  197.   dlink* L2_first = (dir == 0) ? p : p->succ;
  198.   dlink* L2_last =  (L2_first) ? t : nil;
  199.   h = t = 0;
  200.   count = 0;
  201.   L1.h = L1_first;
  202.   L1.t = L1_last;
  203.   L1.count = -1; // size unknown
  204.   if (L1_last) L1_last->succ = 0;
  205.   L2.h = L2_first;
  206.   L2.t = L2_last;
  207.   L2.count = -1; // size unknown
  208.   if (L2_first) L2_first->pred = 0;
  209. }
  210. GenPtr dlist::del(dlink* it)
  211. { if (iterator) error_handler(1,"dlist: deletion while iterator is active");
  212.   if (it==nil)  error_handler(999,"dlist: delete nil-item");
  213.   if (it==h)  return pop();
  214.   if (it==t)  return Pop();
  215.   dlink*  p = it->pred;
  216.   dlink*  s = it->succ;
  217.   GenPtr x = it->e;
  218.   p->succ = s;
  219.   s->pred = p;
  220.   count--;
  221.   delete it;
  222.   return x;
  223. }
  224. dlink* dlist::cyclic_succ(dlink* it) const
  225. { if (it==0) return 0;
  226.   return it->succ? it->succ : h;
  227. }
  228. dlink* dlist::cyclic_pred(dlink* it) const
  229. { if (it==0) return 0;
  230.   return it->pred? it->pred : t;
  231. }
  232. dlink* dlist::max() const
  233. { if (h==0) return 0;
  234.   dlink* m=h;
  235.   dlink* p=m->succ;
  236.   while (p)
  237.   { if (cmp(p->e,m->e) > 0) m=p;
  238.     p=p->succ;
  239.    }
  240.   return m;
  241. }
  242. dlink* dlist::min() const
  243. { if (h==0) return 0;
  244.   dlink* m=h;
  245.   dlink* p=m->succ;
  246.   while (p)
  247.   { if (cmp(p->e,m->e) < 0) m=p;
  248.     p=p->succ;
  249.    }
  250.   return m;
  251. }
  252. void dlist::apply()
  253. { register dlink* p = h;
  254.   while (p)
  255.   { app(p->e);
  256.     p = p->succ;
  257.    }
  258. }
  259. void dlist::permute()
  260.   if (iterator!=0) 
  261.           error_handler(3,"permute: modification while iterator is active");
  262.   length();
  263.   list_item* A = new list_item[count+2];
  264.   list_item x = h;
  265.   int j;
  266.   A[0] = A[count+1] = 0;
  267.  
  268.   for(j=1; j <= count; j++)
  269.   { A[j] = x;
  270.     x = x->succ;
  271.    }
  272.   for(j=1; j<count; j++)  
  273.   { int r = rand_int(j,count);
  274.     x = A[j];
  275.     A[j] = A[r];
  276.     A[r] = x;
  277.    }
  278.   for(j=1; j<=count; j++) 
  279.   { A[j]->succ = A[j+1];
  280.     A[j]->pred = A[j-1];
  281.    }
  282.   h = A[1];
  283.   t = A[count];
  284.   
  285.   delete A;
  286. }
  287.         
  288. void dlist::bucket_sort(int i, int j)
  289. { if (iterator!=0) 
  290.         error_handler(3,"bucket_sort: modification while iterator is active");
  291.   if (h==nil) return; // empty list
  292.   int n = j-i+1;
  293.   register list_item* bucket= new list_item[n+1];
  294.   register list_item* stop = bucket + n;
  295.   register list_item* p;
  296.   register list_item q;
  297.   register list_item x;
  298.   for(p=bucket;p<=stop;p++)  *p = 0;
  299.   while (h) 
  300.   { x = h; 
  301.     h = h->succ;
  302.     int k = ord(x->e);
  303.     if (k >= i && k <= j) 
  304.      { p = bucket+k-i;
  305.        x->pred = *p;
  306.        if (*p) (*p)->succ = x;
  307.        *p = x;
  308.       }
  309.     else 
  310.        error_handler(4,string("bucket_sort: value %d out of range",k)) ;
  311.    }
  312.  for(p=stop; *p==0; p--); 
  313.  // now p points to the end of the rightmost non-empty bucket
  314.  // make it the new head  of the list (remember: list is not empty)
  315.  t = *p;
  316.  t->succ = nil;
  317.  for(q = *p; q->pred; q = q->pred); // now q points to the start of this bucket
  318.  // link buckets together from right to left:
  319.  // q points to the start of the last bucket
  320.  // p points to end of the next bucket
  321.  while(--p >= bucket) 
  322.    if (*p)
  323.    { (*p)->succ = q;
  324.      q->pred = *p;
  325.      for(q = *p; q->pred; q = q->pred); 
  326.     }
  327.  h = q;   // head = start of leftmost non-empty bucket
  328.  delete bucket;
  329. }
  330. void dlist::quick_sort(dlink** l, dlink** r)
  331. { // use virtual cmp function
  332.   register dlink** i = l+(r-l)/2; //rand_int()%(r-l);
  333.   register dlink** k;
  334.  
  335.   if (cmp((*i)->e,(*r)->e)>0) SWAP(i,r);
  336.   SWAP(l,i);
  337.  
  338.   GenPtr s = (*l)->e;
  339.  
  340.   i = l;
  341.   k = r;
  342.   for(;;)
  343.   { while (cmp((*(++i))->e,s)<0);
  344.     while (cmp((*(--k))->e,s)>0);
  345.     if (i<k) SWAP(i,k) else break;
  346.    }
  347.   SWAP(l,k);
  348.   if (k > l+MIN_D) quick_sort(l,k-1);
  349.   if (r > k+MIN_D) quick_sort(k+1,r);
  350. }
  351.         
  352. void dlist::int_quick_sort(dlink** l, dlink** r)
  353. { // use built-in < and > operators for integers
  354.   register dlink** i = l+(r-l)/2; //rand_int()%(r-l);
  355.   register dlink** k;
  356.  
  357.   if ((*i)->e > (*r)->e) SWAP(i,r);
  358.   SWAP(l,i);
  359.  
  360.   int s = LEDA_ACCESS(int,(*l)->e);
  361.  
  362.   i = l;
  363.   k = r;
  364.   for(;;)
  365.   { while (LEDA_ACCESS(int,(*(++i))->e) < s);
  366.     while (LEDA_ACCESS(int,(*(--k))->e) > s);
  367.     if (i<k) SWAP(i,k) else break;
  368.    }
  369.   SWAP(l,k);
  370.   if (k > l+MIN_D) int_quick_sort(l,k-1);
  371.   if (r > k+MIN_D) int_quick_sort(k+1,r);
  372. }
  373. void dlist::insertion_sort(dlink** l, dlink** r, dlink** min_stop)
  374. {
  375.   register dlink** min=l;
  376.   register dlink** run;
  377.   register dlink** p;
  378.   register dlink** q;
  379.   for (run = l+1; run <= min_stop; run++)
  380.       if (cmp((*run)->e,(*min)->e) < 0) min = run;
  381.   SWAP(min,l);
  382.   if (r == l+1) return; 
  383.   for(run=l+2; run <= r; run++)
  384.   { for (min = run-1; cmp((*run)->e,(*min)->e) < 0; min--);
  385.     min++;
  386.     if (run != min) 
  387.     { dlink* save = *run;
  388.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  389.       *min = save;
  390.      }
  391.    }
  392. }
  393. void dlist::int_insertion_sort(dlink** l, dlink** r, dlink** min_stop)
  394. {
  395.   register dlink** min=l;
  396.   register dlink** run;
  397.   register dlink** p;
  398.   register dlink** q;
  399.   for (run = l+1; run <= min_stop; run++)
  400.     if (LEDA_ACCESS(int,(*run)->e) < LEDA_ACCESS(int,(*min)->e)) min = run;
  401.   SWAP(min,l);
  402.   if (r == l+1) return; 
  403.   for(run=l+2; run <= r; run++)
  404.   { for (min=run-1;LEDA_ACCESS(int,(*run)->e)<LEDA_ACCESS(int,(*min)->e);min--);
  405.     min++;
  406.     if (run != min) 
  407.     { dlink* save = *run;
  408.       for(p=run, q = run-1; p > min; p--,q--) *p = *q;
  409.       *min = save;
  410.      }
  411.    }
  412. }
  413. void dlist::sort()
  414. { if (iterator!=0)
  415.       error_handler(1,"sort: modification while iterator is active");
  416.   if (length() <= 1) return;    // nothing to sort
  417.   dlink** A = new dlink*[count+2];
  418.   register dlink*  loc = h;
  419.   register dlink** p;
  420.   register dlink** stop = A+count+1;
  421.   dlink** left  = A+1;
  422.   dlink** right = A+count;
  423.   dlink** min_stop = left + MIN_D;
  424.   if (min_stop > right) min_stop = right;
  425. min_stop = right;
  426.   for(p=A+1; p<stop; p++)
  427.   { *p = loc;
  428.     loc = loc->succ;
  429.    }
  430.   if (int_type())
  431.      { int_quick_sort(left,right);
  432.        int_insertion_sort(left,right,min_stop);
  433.       }
  434.    else
  435.      { quick_sort(left,right);
  436.        insertion_sort(left,right,min_stop);
  437.       }
  438.   *A = *stop = 0;
  439.   for (p=A+1;p<stop;p++) 
  440.   { (*p)->succ = *(p+1);
  441.     (*p)->pred = *(p-1);
  442.    }
  443.   h = A[1];
  444.   t = A[count];
  445.   delete A;
  446. }
  447. dlist& dlist::operator=(const dlist& x)
  448. { register dlink* p;
  449.   clear();
  450.   for (p = x.h; p; p = p->succ) append(p->e); 
  451.   if (!int_type())
  452.     for (p = h; p; p = p->succ) copy_el(p->e);
  453.                                 
  454.   return *this;
  455. }
  456. dlist dlist::operator+(const dlist& x)  // concatenation
  457. { dlist y = x;
  458.   dlink* p = t;
  459.   while (p) { y.push(p->e);    
  460.               x.copy_el(p->e);
  461.               p = p->pred;}
  462.   return y;
  463. }
  464. void dlist::clear()
  465. { if (h==nil) return;
  466.   if (!int_type())
  467.     for(dlink* p = h; p; p = p->succ) clear_el(p->e);
  468.   deallocate_list(h,t,sizeof(dlink));
  469.   iterator=h=t=nil;
  470.   count=0;
  471. }
  472. void dlist::print(ostream& out, string s, char space) const
  473. { list_item l = h;
  474.   cout << s;
  475.   if (l)
  476.   { print_el(l->e,out); 
  477.     l = l->succ;
  478.     while (l)
  479.       { out << string(space);
  480.         print_el(l->e,out); 
  481.         l = l->succ;
  482.        }
  483.   }
  484.   out.flush();
  485. }
  486. void dlist::read(istream& in, string s, int delim)
  487. { char c;
  488.   GenPtr x;
  489.   cout << s;
  490.   clear();
  491.   if (delim == EOF)
  492.      for(;;)
  493.      { while (in.get(c) && isspace(c));
  494.        if (!in) break;
  495.        in.putback(c);
  496.        read_el(x,in); 
  497.        append(x);
  498.       }
  499.   else
  500.      for(;;)
  501.      { while (in.get(c) && isspace(c) && c!=delim);
  502.        if (!in || c==delim) break;
  503.        in.putback(c);
  504.        read_el(x,in); 
  505.        append(x);
  506.       }
  507. }