home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / basic / _list.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  10.9 KB  |  575 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _list.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/list.h>
  16.  
  17. /*  Definition  der Member-Funktionen der Klasse "dlist"
  18.     (doppelt verkettete Listen)
  19.  
  20.     Stefan Naeher
  21.     FB10 Informatik 
  22.     Universitaet des Saarlandes 
  23.     6600 Saarbruecken
  24.  
  25.     September 1988
  26.     
  27. */
  28.  
  29. //------------------------------------------------------------------------------
  30. // Members of class dlist: base class for all lists
  31. //------------------------------------------------------------------------------
  32.  
  33. dlist::dlist()      
  34. { h=0; 
  35.   t=0;
  36.   count=0;
  37.   iterator=0; 
  38. }
  39.  
  40. dlist::dlist(ent a) 
  41. { h=t=new dlink(a,0,0);
  42.   count=1; 
  43.   iterator=0;  
  44. }
  45.  
  46. dlist::dlist(const dlist& x)
  47. { h=0; 
  48.   t=0; 
  49.   count=0; 
  50.   iterator=0;
  51.  
  52.   dlink* p = x.h;
  53.                               
  54.   while (p) { x.copy_el(p->e); /* copy list using virtual copy_el of x !! */
  55.               append(p->e);    // does not make a copy  !!
  56.               p = p->succ; 
  57.              }
  58. }
  59.  
  60. //------------------------------------------------------------------------------
  61. // Iteration:
  62. //------------------------------------------------------------------------------
  63.  
  64. dlink* dlist::move_iterator(int dir) const 
  65. { if (iterator) 
  66.      set_iterator(dir ? iterator->pred : iterator->succ);
  67.   else 
  68.      set_iterator(dir ? t : h);
  69.   return iterator;
  70.  } 
  71.  
  72. bool dlist::current_element(ent& x) const 
  73. { if (iterator) 
  74.   { x = iterator->e; 
  75.     return true; 
  76.    } 
  77.   return false; 
  78.  }
  79.  
  80. bool dlist::next_element(ent& x)    const 
  81. { if (iterator) 
  82.      set_iterator(iterator->succ);
  83.   else 
  84.      set_iterator(h);
  85.  
  86.   if (iterator) 
  87.   { x = iterator->e;
  88.     return true; 
  89.    } 
  90.   return false; 
  91.  }
  92.  
  93. bool dlist::prev_element(ent& x)  const
  94. { if (iterator) 
  95.      set_iterator(iterator->pred);
  96.   else 
  97.      set_iterator(t);
  98.  
  99.   if (iterator) 
  100.   { x = iterator->e;
  101.     return true; 
  102.    } 
  103.   return false; 
  104.  }
  105.  
  106. //------------------------------------------------------------------------------
  107.  
  108. dlink* dlist::get_item(int i) const
  109. { dlink* p = h;
  110.   while ( p && i--) p = p->succ; 
  111.   return p;
  112. }
  113.  
  114. dlink* dlist::succ(dlink* p, int i)  const
  115. { while ( p && i--) p = p->succ; 
  116.   return p;
  117. }
  118.  
  119. dlink* dlist::pred(dlink* p, int i) const
  120. { while ( p && i--) p = p->pred; 
  121.   return p;
  122. }
  123.  
  124. dlink* dlist::search(ent x) const  /* linear search */
  125. { dlink* p = h;
  126.   while ( p && (p->e != x)) p = p->succ; 
  127.   return p;
  128.  
  129. int dlist::rank(ent x)   const   /* rank by linear search */
  130. { dlink* p = h;
  131.   int r = 1;
  132.   while ( p && (p->e != x)) 
  133.   { p = p->succ; 
  134.     r++;
  135.    }
  136.   return (p) ? r : 0;
  137.  
  138. void dlist::pop()    
  139. { if (iterator!=0) error_handler(1,"pop: deletion while iterator is active");
  140.   dlink* x=h; 
  141.   if (count==0) return;
  142.   if (--count) { h = h->succ; h->pred = 0; }
  143.   else  h = t = 0;
  144.   clear_el(x->e);
  145.   delete x;
  146. }
  147.  
  148. void dlist::Pop()    
  149. { if (iterator!=0) error_handler(1,"Pop: deletion while iterator is active");
  150.   dlink* x=t; 
  151.   if (count==0) return;
  152.   if (--count) { t = t->pred; t->succ = 0; }
  153.   else  h = t = 0;
  154.   clear_el(x->e);
  155.   delete x;
  156. }
  157.  
  158. dlink* dlist::insert(ent a, dlink* l, int dir) 
  159.   if (iterator!=0) error_handler(2,"insert: insertion while iterator is active");
  160.  
  161.   if (l==0) return dir ? append(a) : push(a); 
  162.  
  163.   dlink* s=l->succ;
  164.   dlink* p=l->pred;
  165.   dlink* n;
  166.   
  167.   if (dir==0) //insert after l
  168.   { n= new dlink(a,l,s);
  169.     l->succ = n;
  170.     if (l==t) t=n;
  171.     else s->pred = n;}
  172.  
  173.   else //insert before l
  174.   { n= new dlink(a,p,l);
  175.     l->pred = n;
  176.     if (l==h) h=n;
  177.     else p->succ = n;}
  178.  
  179.   count++;
  180.  
  181.   return n;
  182. }
  183.  
  184. dlink* dlist::push(ent a)   
  185. { if (iterator!=0) error_handler(2,"push: insertion while iterator is active");
  186.   count++;
  187.   if (h) h = h->pred = new dlink(a,0,h); 
  188.   else   h = t =  new dlink(a,0,0);
  189.   return h;
  190. }
  191.  
  192. dlink* dlist::append(ent a)
  193. { if(iterator!=0) error_handler(2,"append: insertion while iterator is active");
  194.   count++;
  195.   if (t) t = t->succ = new dlink(a,t,0);
  196.   else   t = h = new dlink(a,0,0);
  197.   return t; 
  198.  
  199. void dlist::conc(dlist& l)
  200. { if (iterator!=0) error_handler(2,"conc: iterator is active");
  201.  if (t) { t->succ = l.h;
  202.           if (l.h) { l.h->pred = t; t = l.t; } }
  203.    else { h = l.h; t = l.t; }
  204.  count = count+l.count;
  205.  l.h = l.t = 0;
  206.  l.count = 0;
  207. }
  208.  
  209.  
  210. void dlist::split(dlink* p, dlist& l1, dlist& l2)
  211. { if (iterator!=0) 
  212.    error_handler(1,"list: split while iterator is active");
  213.  
  214.   //if (p==nil) error_handler(888,"split at nil item");
  215.  
  216.   l1.clear();
  217.   l2.clear();
  218.  
  219.   if (p==nil)    // l1 = empty,  l2 = l, l = empty;
  220.   { l2.h = h;
  221.     l2.t = t;
  222.     l2.count = count;
  223.     h = t = 0;
  224.     count = 0;
  225.     return;
  226.    }
  227.  
  228.   if (h == 0) return;   /* empty list */
  229.  
  230.  
  231.   if (p->pred)
  232.   { l1.h = h;
  233.     l1.t = p->pred;
  234.     p->pred->succ = 0;
  235.    }
  236.  
  237.   p->pred = 0;
  238.   l2.h = p;
  239.   l2.t = t;
  240.  
  241.  
  242.   // have to set counters
  243.   // "count the smaller half" gives amortized n log n  bound
  244.  
  245.   dlink* l = l1.h;
  246.   dlink* r = l2.h;
  247.   int    c = 0;
  248.  
  249.   while (l && r)
  250.   { l = l->succ;
  251.     r = r->succ;
  252.     c++;
  253.    }
  254.  
  255.   if (l==0)   // left end reached first
  256.   { l1.count = c;
  257.     l2.count = count - l1.count;
  258.    }
  259.  
  260.   else
  261.   { l2.count = c;
  262.     l1.count = count - l2.count;
  263.    }
  264.  
  265.   /* make original list empty */
  266.   
  267.   h = t = 0;
  268.   count = 0;
  269.  
  270. }
  271.  
  272.  
  273. void dlist::del(dlink* loc)
  274. { if (iterator!=0) 
  275.    error_handler(1,"dlist::del: deletion while iterator is active");
  276.  
  277.   if (loc==0)   
  278.    error_handler(999,"dlist::del: item = nil");
  279.  
  280.   if (loc==h)  { pop(); return; }
  281.  
  282.   if (loc==t)  { Pop(); return; }
  283.   
  284.  
  285.   dlink* p = loc->pred;
  286.   dlink* s = loc->succ;
  287.   p->succ = s;
  288.   s->pred = p;
  289.   count--;
  290.  
  291.   clear_el(loc->e);
  292.   delete loc;
  293. }
  294.  
  295. dlink* dlist::cyclic_succ(dlink* loc) const
  296. { if (loc==0) return 0;
  297.   return loc->succ? loc->succ : h;
  298. }
  299.  
  300. dlink* dlist::cyclic_pred(dlink* loc) const
  301. { if (loc==0) return 0;
  302.   return loc->pred? loc->pred : t;
  303. }
  304.  
  305. dlink* dlist::max(CMP_ENT f) const
  306. { if (h==0) return 0;
  307.   dlink* m=h;
  308.   dlink* p=m->succ;
  309.  
  310.   if (f) // use cmp function f
  311.      while (p)
  312.      { if (f(p->e,m->e)) m=p;
  313.        p=p->succ;
  314.       }
  315.   else  /* // use virtual cmp function  
  316.            while (p)
  317.            { if (cmp(p->e,m->e)) m=p;
  318.              p=p->succ;
  319.             }
  320.          */
  321.         error_handler(1,"list: max needs cmp function parameter");
  322.  
  323.   return m;
  324. }
  325.  
  326. dlink* dlist::min(CMP_ENT f) const
  327. { if (h==0) return 0;
  328.   dlink* m=h;
  329.   dlink* p=m->succ;
  330.  
  331.   if (f) // use cmp function f
  332.      while (p)
  333.      { if (f(m->e,p->e)) m=p;
  334.        p=p->succ;
  335.      }
  336.   else  /* // use virtual cmp function  
  337.            while (p)
  338.            { if (cmp(m->e,p->e)) m=p;
  339.              p=p->succ;
  340.             }
  341.          */
  342.         error_handler(1,"list: min needs cmp function parameter");
  343.  
  344.   return m;
  345. }
  346.  
  347. void dlist::apply(ENT_TO_VOID f)
  348. { dlink* p = h;
  349.  
  350.   while (p)
  351.   { f(p->e);
  352.     p = p->succ;
  353.   }
  354. }
  355.  
  356. void dlist::permute()
  357.   if (iterator!=0) error_handler(3,"permute: modification while iterator is active");
  358.  
  359.   list_item* A = new list_item[count+2];
  360.   list_item x = h;
  361.   int j;
  362.  
  363.   A[0] = A[count+1] = 0;
  364.  
  365.   for(j=1; j <= count; j++)
  366.   { A[j] = x;
  367.     x = x->succ;
  368.    }
  369.  
  370.   init_random();
  371.  
  372.   for(j=1; j<count; j++)  
  373.   { int r = random(j,count);
  374.     if (j!=r) SWAP(A[j],A[r]);
  375.    }
  376.  
  377.   for(j=1; j<=count; j++) 
  378.   { A[j]->succ = A[j+1];
  379.     A[j]->pred = A[j-1];
  380.    }
  381.  
  382.   h = A[1];
  383.   t = A[count];
  384.   
  385.   delete A;
  386. }
  387.         
  388.  
  389. void dlist::bucket_sort(int i, int j, ENT_TO_INT f)
  390. { if (iterator!=0) error_handler(3,"bucket_sort: modification while iterator is active");
  391.   int k;
  392.   dlist* bucket= new dlist[j-i+1];
  393.   ent e;
  394.  
  395.   while (count) { e = head(); 
  396.                   copy_el(e);
  397.                   pop();      // destroys one copy
  398.                   k = f(e);
  399.                   if ((k>=i)&&(k<=j)) bucket[k-i].append(e);
  400.                   else error_handler(4,"bucket_sort: value out of range") ;
  401.                  }
  402.  for (k=i;k<=j;k++) 
  403.      while (bucket[k-i].count) 
  404.        { e = bucket[k-i].head();
  405.          append(e);
  406.          bucket[k-i].pop();    // no destroy  in dlist::pop
  407.         }
  408.  
  409.  delete (char*)bucket;
  410. }
  411.  
  412. /*
  413. void dlist::quick_sort(dlink** A,int l, int r)
  414. { // use virtual cmp routine (member of dlist)
  415.  
  416.   register int i = l;
  417.   register int k = r+1;
  418.   ent s = A[l]->e;
  419.   //dlink* t;
  420.  
  421.   while (i<k)
  422.   { while (i < r && cmp(A[++i]->e,s) < 0);
  423.     while (k > l && cmp(A[--k]->e,s) > 0);
  424.     if (k>i) SWAP(A[i],A[k]);
  425.    }
  426.  
  427.   SWAP(A[l],A[k]);
  428.  
  429.   if (l < k-1) quick_sort(A,l,k-1);
  430.   if (r > k+1) quick_sort(A,k+1,r);
  431. }
  432. */
  433.  
  434.         
  435. void dlist::quick_sort(dlink** A,int l, int r, CMP_ENT cmp_fct)
  436. { // use ordering defined by cmp_fct(ent& x,ent& y)
  437.  
  438.   register int i = l;
  439.   register int k = r+1;
  440.   ent s = A[l]->e;
  441.   //dlink* t;
  442.  
  443.   while (i<k)
  444.   { while (i<r && cmp_fct(A[++i]->e,s)<0);
  445.     while (k>l && cmp_fct(A[--k]->e,s)>0);
  446.     if (k>i) SWAP(A[i],A[k]);
  447.    }
  448.  
  449.   SWAP(A[l],A[k]);
  450.  
  451.   //t = A[l];
  452.   //A[l] = A[k];
  453.   //A[k] = t;
  454.  
  455.   if (l < k-1) quick_sort(A,l,k-1,cmp_fct);
  456.   if (r > k+1) quick_sort(A,k+1,r,cmp_fct);
  457. }
  458.  
  459. void dlist::sort(CMP_ENT cmp_fct)
  460. { if (iterator!=0)
  461.       error_handler(1,"sort: modification while iterator is active");
  462.  
  463.   if (count==0) return;    // nothing to sort
  464.  
  465.   register int i;
  466.   register dlink* loc = h;
  467.   dlink** A = new dlink*[count+2];
  468.  
  469.   A[0] = A[count+1] = 0;
  470.  
  471.   for(i=1;i<=count;i++)
  472.   { A[i] = loc;
  473.     loc = loc->succ;
  474.    }
  475.  
  476.   init_random();
  477.  
  478.   for(i=1;i<=count;i++) 
  479.     { int j = random(1,count);    // random permutation
  480.        if (i!=j) SWAP(A[i],A[j]);  
  481.      }
  482.  
  483.   if (cmp_fct)
  484.        quick_sort(A,1,count,cmp_fct);
  485.   else // quick_sort(A,1,count);
  486.        error_handler(1,"list: sort needs cmp function parameter");
  487.  
  488.   for (i=1;i<=count;i++) 
  489.   { A[i]->succ = A[i+1];
  490.     A[i]->pred = A[i-1];
  491.    }
  492.  
  493.   h = A[1];
  494.   t = A[count];
  495.  
  496.   delete A;
  497.  }
  498.         
  499.  
  500. dlist& dlist::operator=(const dlist& x)
  501. { iterator=0;
  502.   clear();
  503.  
  504.   dlink* p = x.h;         
  505.                                 
  506.   while (p) { copy_el(p->e);
  507.               append(p->e);  // does not make a copy !!!
  508.               p = p->succ;
  509.              }
  510.   return *this;
  511. }
  512.  
  513. dlist dlist::operator+(const dlist& x)  // concatenation
  514. {
  515.  dlist y = x;
  516.   dlink* p = t;
  517.   while (p) { x.copy_el(p->e);
  518.               y.push(p->e);    
  519.               p = p->pred;}
  520.   return y;
  521. }
  522.  
  523. void dlist::clear()
  524. { if (h==nil) return;
  525.   register dlink* p = h;
  526.   while (p) 
  527.   { clear_el(p->e);
  528.     p = p->succ;
  529.     //delete h;
  530.     //h = p;
  531.    }
  532.   deallocate_list(h,t,3);
  533.   h=0;
  534.   t=0;
  535.   iterator=0;
  536.   count=0;
  537. }
  538.  
  539. void dlist::print(ostream& out, string s, char space) const
  540. { list_item l = h;
  541.   cout << s;
  542.   if (l)
  543.   { print_el(l->e,out); 
  544.     l = l->succ;
  545.     while (l)
  546.       { out << chr(space);
  547.         print_el(l->e,out); 
  548.         l = l->succ;
  549.        }
  550.   }
  551.   out.flush();
  552. }
  553.  
  554. void dlist::read(istream& in, string s, char delim)
  555. { char c;
  556.   ent x;
  557.   cout << s;
  558.  
  559.   clear();
  560.   while (in)
  561.   { in.get(c);
  562.     if (c==delim) break;
  563.     in.putback(c);
  564.     read_el(x,in); // creates an object 
  565.     append(x);     // makes no copy   (dlist)
  566.    }
  567.  
  568. }
  569.