home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ledar34.zip / leda-r-3_4_tar / LEDA-3.4 / src / plane / _ps_tree.c < prev    next >
C/C++ Source or Header  |  1996-09-03  |  18KB  |  686 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA 3.4
  4. +
  5. +  _ps_tree.c
  6. +
  7. +  This file is part of the LEDA research version (LEDA-R) that can be 
  8. +  used free of charge in academic research and teaching. Any commercial
  9. +  use of this software requires a license which is distributed by the
  10. +  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
  11. +  (fax +49 681 31104).
  12. +
  13. +  Copyright (c) 1991-1996  by  Max-Planck-Institut fuer Informatik
  14. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  15. +  All rights reserved.
  16. *******************************************************************************/
  17. //--------------------------------------------------------------------
  18. //  
  19. //  Priority Search Trees
  20. //
  21. //  Renate Lassen   (1990)
  22. //
  23. // Implementation follows
  24. // Kurt Mehlhorn: Data Structures and Algorithms 3, section III.5.1.2
  25. //
  26. // -------------------------------------------------------------------
  27.  
  28. #include <LEDA/impl/ps_tree.h>
  29.  
  30.  
  31. // -------------------------------------------------------------
  32. // member functions
  33. // -------------------------------------------------------------
  34.  
  35. // -------------------------------------------------------------
  36. // lrot() , rrot() , ldrot() , rdrot()
  37. // Rotationen am Knoten p
  38.  
  39. void ps_tree::lrot(ps_item p, ps_item q)
  40.   x_typ xh ,yh;
  41.  
  42. //  cout << "lrot\n";
  43. //  cout << "p :" << p->split_value_x() << "\n";
  44. //  cout << "q :" << q->split_value_x() << "\n";
  45.   ps_item h = p->sohn[right];
  46. //  cout << "h :" << h->split_value_x() << "\n";
  47.   xh = h->x_value();
  48.   yh = h->y_value();
  49.   
  50.   p->sohn[right] = h->sohn[left];
  51.   h->sohn[left] = p;
  52.    
  53.   if (!q) root=h;
  54.   else
  55.   {
  56.    if ( p == q->sohn[left] )   q->sohn[left]=h;
  57.    else q->sohn[right]=h;
  58.   }; 
  59.   
  60.   h->x_val = p->x_value();
  61.   h->y_val = p->y_value();
  62.   p->x_val = p->y_val = 0;
  63.  
  64.   if (cmp(xh,yh,h->split_value_x(),h->split_value_y())>0)  
  65.       sink(h->sohn[right],xh,yh);
  66.   else  sink(p->sohn[right],xh,yh); 
  67.     
  68.   fill(p);
  69.   
  70.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  71.   h->gr=p->groesse()+h->sohn[right]->groesse();
  72. }
  73.  
  74. void ps_tree::rrot(ps_item p, ps_item q)
  75.   x_typ xh, yh;
  76.   
  77.   //cout << "rrot\n"; 
  78.  // cout << "p :" << p->split_value_x() << "\n";
  79.  // cout << "q :" << q->split_value_x() << "\n";
  80.   ps_item h = p->sohn[left];
  81.  // cout << "h :" << h->split_value_x() << "\n";
  82.   xh=h->x_value();
  83.   yh=h->y_value();
  84.   
  85.   p->sohn[left] = h->sohn[right];
  86.   h->sohn[right] = p;
  87.  
  88.   if (!q) root=h;
  89.   else
  90.   {
  91.    if ( p == q->sohn[left] ) q->sohn[left] = h;
  92.    else q->sohn[right] = h; 
  93.   };
  94.  
  95.   h->x_val = p->x_value();
  96.   h->y_val = p->y_value();
  97.   p->x_val = p->y_val = 0;
  98.   
  99.   if (cmp(xh,yh,h->split_value_x(),h->split_value_y())<=0)  
  100.       sink(h->sohn[left],xh,yh);
  101.   else sink(p->sohn[left],xh,yh);
  102.   
  103.   fill(p);
  104.  
  105.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  106.   h->gr=p->groesse()+h->sohn[left]->groesse();
  107. }
  108.  
  109. void ps_tree::ldrot(ps_item p, ps_item q)
  110.     
  111.   //cout << "ldrot\n";
  112.   ps_item h = p->sohn[right];
  113.   //ps_item t = h->sohn[left];
  114.   rrot(h,p);
  115.   lrot(p,q);
  116.  // cout << "p:" << p->split_value_x() << "\n";
  117.  // cout << "h:" << h->split_value_x() << "\n";
  118. }
  119.  
  120. void ps_tree::rdrot(ps_item p, ps_item q)
  121. {
  122.  
  123.   //cout << "rdrot\n";
  124.   ps_item h = p->sohn[left];
  125.   //ps_item t = h->sohn[right];
  126.   lrot(h,p);
  127.   rrot(p,q);
  128.  // cout << "p:" << p->split_value_x() << "\n";
  129.   //cout << "h:" << h->split_value_x() << "\n";
  130.   //cout << "t:" << t->split_value() << "\n";
  131. }
  132.  
  133. // ------------------------------------------------------------------
  134. // fill(ps_item)
  135. // fuellt Knoten bei Rotation wieder auf 
  136.   
  137. void ps_tree::fill(ps_item p)
  138. {
  139.  
  140.  int leer=0;
  141.  int diff=0;
  142.  //cout << "fill\n";
  143.  while (!p->blatt() && leer!=1)
  144.  {
  145.   diff=cmp(p->sohn[left]->y_value(),p->sohn[right]->y_value()); 
  146.   //cout << "diff = " << diff << "\n";
  147.   if (diff==0) leer=1;                                           // Kinder von p gefuellt ?
  148.   else if ( (diff<0 && p->sohn[left]->y_value()!=0) 
  149.             || (diff>0 && p->sohn[right]->y_value()==0))
  150.        {
  151.         p->x_val = p->sohn[left]->x_value();
  152.         p->y_val = p->sohn[left]->y_value();
  153.         p->sohn[left]->x_val = p->sohn[left]->y_val = 0;   
  154.   //cout <<"gefuellt von links :"<<p->split_value()<<":"<<p->x_value()<<":"<<p->y_value()<<"\n";
  155.         p = p->sohn[left];
  156.        }
  157.        else if ( (diff>0 && p->sohn[right]->y_value()!=0) 
  158.                  || (diff<0 && p->sohn[left]->y_value()==0)) 
  159.             {
  160.             p->x_val = p->sohn[right]->x_value();
  161.             p->y_val = p->sohn[right]->y_value();
  162.             p->sohn[right]->x_val = p->sohn[right]->y_val = 0;   
  163.             p->sohn[right]->x_val = p->sohn[right]->y_val =0;
  164.             p = p->sohn[right];
  165.             };
  166.  };
  167. }
  168.  
  169. // ------------------------------------------------------------------
  170. // sink() 
  171. // laesst Paar (x,y) im Unterbaum mit Wurzel p herabsinken.
  172.    
  173. ps_item ps_tree::sink(ps_item q, x_typ x, x_typ y)
  174. {
  175.  x_typ xh, yh, xneu=x;
  176.  x_typ yneu=y;
  177.  ps_item p =q;
  178.  ps_item inserted; 
  179.  
  180.  while(!p->blatt() && cmp(p->x_value(),0)!=0)
  181.  {
  182.   //cout << "sink\n";
  183.   //cout << p->split_value_x() << ":" << p->split_value_y() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  184.   if (cmp(p->y_value(),0)!=0 && cmp(y,p->y_value())<0)
  185.   {                                                    // Tausch
  186.    xh=p->x_value();
  187.    yh=p->y_value();
  188.    p->x_val=x;
  189.    p->y_val=y;
  190.    x=xh;
  191.    y=yh;
  192.    if (cmp(p->x_value(),xneu)==0 && cmp(p->y_value(),yneu)==0) inserted=p;
  193.   //cout << "inserted in Tausch\n";
  194.   //cout << inserted->split_value() <<":"<< inserted->x_value() << ":" << inserted->y_value() <<"\n";
  195.   };
  196.   //cout << "hallo\n";
  197.   if (cmp(x,y,p->split_value_x(),p->split_value_y())<=0)   p=p->sohn[left];
  198.   else 
  199.   {
  200.    p=p->sohn[right]; 
  201.   //cout << p->split_value_x() << ":" << p->split_value_y() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  202.   };
  203.  };
  204.  p->x_val=x;
  205.  p->y_val=y;
  206.  if (cmp(p->x_value(),xneu)==0 && cmp(p->y_value(),yneu)==0) inserted=p;
  207.  // cout << "inserted" << inserted->split_value_y() <<":"<< inserted->x_value() << ":" << inserted->y_value() <<"\n";
  208.  return inserted;
  209. }
  210.  
  211. // ------------------------------------------------------------------
  212. // search(x_typ,x_typ)
  213. // sucht Knoten, der das Paar (x,y) enthaelt,
  214. // oder Blatt, an dem neues Blatt fuer x angehaengt werden soll.
  215.  
  216.  
  217. ps_item ps_tree::search(x_typ x,x_typ y)
  218. {
  219.  ps_item p = root;
  220.  //ps_item q = 0;
  221.  
  222. // cout << "search\n";
  223.  if (root->blatt())
  224.  {
  225.   st.push(root);
  226.   return p;
  227.  }
  228.  else
  229.  {
  230.   st.push(p);
  231.   while ( !p->blatt() && p!=0 )
  232.   {
  233.    if ( cmp(x,p->x_value())==0 && cmp(y,p->y_value())==0) 
  234.    {
  235.     p=0;
  236.    }
  237.    else 
  238.    { 
  239.     if ( cmp(x,y,p->split_value_x(),p->split_value_y())<=0 ) p=p->sohn[left];
  240.     else p=p->sohn[right]; 
  241.     st.push(p);
  242.    }
  243.   }
  244.   return p;
  245.  }
  246. }  
  247.  
  248.   
  249. // ------------------------------------------------------------------
  250. // locate(x_typ x,x_typ y)
  251. // gibt Knoten oder Blatt mit Inhalt (x,y), falls existiert,
  252. //                                      0 , sonst.
  253.  
  254. ps_item ps_tree::locate(x_typ x,x_typ y)
  255. {
  256.  ps_item p = root;
  257.  ps_item q = 0;
  258.  
  259.  //cout << "locate\n";
  260.  while ( q==0 && p!=0 && cmp(y,p->y_value())>=0 )
  261.  {
  262.   st.push(p);
  263.   if ( cmp(x,p->x_value())==0 && cmp(y,p->y_value())==0) 
  264.   {
  265.    q=p;
  266.   }
  267.   else 
  268.   { 
  269.    if ( cmp(x,y,p->split_value_x(),p->split_value_y())<=0 ) p=p->sohn[left];
  270.    else p=p->sohn[right]; 
  271.   }
  272.  }
  273.  return q;
  274. }
  275.  
  276. // ------------------------------------------------------------------
  277. // delleaf(ps_item)
  278. // loescht Blatt von Paar (x,y) und Vater des Blattes.
  279. // ( Zwei Blaetter mit gemeinsamen Vater sind nie beide gefuellt. )
  280.   
  281. void ps_tree::delleaf(ps_item q)
  282. {
  283.  ps_item p;    
  284.  ps_item t;    
  285.  ps_item father;
  286.  x_typ xh,yh;
  287.  
  288.  //cout << "delleaf\n";
  289.  q->x_val=0;
  290.  q->y_val=0;
  291.  p=st.pop();
  292.  father=st.pop();
  293.  if (q==father->sohn[left] ) father->sohn[left]=0;
  294.  else father->sohn[right]=0;
  295.  delete (q);                                           // loescht Blatt
  296.  t= st.empty() ? 0 : st.top();
  297.  xh=father->x_value();
  298.  yh=father->y_value();
  299.  //cout << "xh: " << xh << "\n";
  300.  //cout << "yh: " << yh << "\n";
  301.   
  302.  if ( father->sohn[left]!=0) q=father->sohn[left];
  303.  else q=father->sohn[right];
  304.  if (t!=0)
  305.  {
  306.   if (father==t->sohn[left])  t->sohn[left]=q;
  307.   else  t->sohn[right]=q;
  308.  }
  309.  else root=q;
  310.  delete(father);                                       // loescht Vater
  311.  
  312.  //cout << "q-x_value: " << q->x_value() << "\n";
  313.  //cout << "q-y_value: " << q->y_value() << "\n";
  314.  //cout << "q-split_value: " << q->split_value() << "\n";
  315.  sink(q,xh,yh);
  316. }
  317.   
  318. // ------------------------------------------------------------------
  319. // insert(x_typ x,x_typ y)
  320. // fuegt ein neues Item (x,y) in den Baum ein
  321. //                 , falls noch nicht vorhanden, 
  322. // Fehlermeldung   ,sonst
  323. // gibt Zeiger auf eingefuegtes Blatt zurueck
  324.  
  325. ps_item ps_tree::insert(x_typ x,x_typ y)
  326.  ps_item p;
  327.  ps_item t;
  328.  ps_item father;
  329.  
  330.  if (!root)                                     // neuer Baum
  331.  {  
  332.   ps_item p=new ps_node(x,y,x,y);
  333.   root=p; 
  334.   anzahl=1; 
  335.   return p;
  336.  }
  337.  else
  338.  {
  339.   p=search(x,y);
  340.   //cout << "p-x_value: " << p->x_value() << "\n";
  341.   //cout << "p-y_value: " << p->y_value() << "\n";
  342.   //cout << "p-split_value_x: " << p->split_value_x() << "\n";
  343.   //cout << "p-split_value_y: " << p->split_value_y() << "\n";
  344.   
  345.   if (p==0)
  346.   {
  347.    error_handler(0,"point already there !");   // Warnung
  348.    st.clear();
  349.    return p;
  350.   }
  351.   else
  352.   {
  353.    ps_item q = new ps_node(0,0,p->split_value_x(),p->split_value_y());   
  354.    ps_item w = new ps_node(0,0,x,y);           // zwei neue Blaetter
  355.   //cout << "q-x_value: " << q->x_value() << "\n";
  356.   //cout << "q-y_value: " << q->y_value() << "\n";
  357.   //cout << "q-split_value_x: " << q->split_value_x() << "\n";
  358.   //cout << "q-split_value_y: " << q->split_value_y() << "\n";
  359.   //cout << "w-x_value: " << w->x_value() << "\n";
  360.   //cout << "w-y_value: " << w->y_value() << "\n";
  361.   //cout << "w-split_value_x: " << w->split_value_x() << "\n";
  362.   //cout << "w-split_value_y: " << w->split_value_y() << "\n";
  363.    if(cmp(p->split_value_x(),p->split_value_y(),x,y)<=0)
  364.    {
  365.     p->sohn[left]=q; 
  366.     p->sohn[right]=w; 
  367.    }
  368.    else
  369.    {
  370.     p->split_val[0] = x;
  371.     p->split_val[1] = y;
  372.     p->sohn[left]=w;
  373.     p->sohn[right]=q;
  374.    } 
  375.                    
  376.   //cout << "p-x_value: " << p->x_value() << "\n";
  377.   //cout << "p-y_value: " << p->y_value() << "\n";
  378.   //cout << "p-split_value_x: " << p->split_value_x() << "\n";
  379.   //cout << "p-split_value_y: " << p->split_value_y() << "\n";
  380.    while (!st.empty())                          // rebalancieren
  381.    { 
  382.     t=st.pop();
  383.    // cout << "stack\n";
  384.     father = st.empty() ? 0 : st.top();
  385.     t->gr++;  
  386.     float i = t->bal();
  387.   
  388.     //cout << "i" << i << "\n";
  389.     if (i < alpha)
  390.     {
  391.      if (t->sohn[right]->bal()<=d) lrot(t,father);
  392.      else ldrot(t,father);
  393.     }
  394.     else if (i>1-alpha) 
  395.     {
  396.       if (t->sohn[left]->bal() > d ) rrot(t,father);
  397.       else rdrot(t,father);
  398.     }
  399.    }
  400.    p = sink(root,x,y);
  401.    //cout<< p->split_value() <<":"<< p->x_value() << ":" << p->y_value() <<"\n";
  402.    return p;
  403.   }
  404.  } 
  405. }
  406. // ------------------------------------------------------------------
  407. // del()
  408. // loescht Item it im Baum mit x_value(it) = x ,
  409. //                             y_value(it) = y , falls existiert
  410. //         und gibt Zeiger auf it zurueck
  411. // 0 , sonst
  412.  
  413. ps_item ps_tree::del(x_typ x,x_typ y)
  414.  ps_item p;
  415.  ps_item t;
  416.  ps_item father;
  417.  ps_item deleted = new ps_node(x,y,0,0);
  418.  
  419.  if (root==0) 
  420.  {
  421.   error_handler(0,"Tree is empty");
  422.   return 0;                                          // leerer Baum
  423.  }
  424.  else
  425.  {
  426.   p=locate(x,y);
  427.   //cout << "located:"<<p->split_value()<<"\n";
  428.   if (p==0) 
  429.   {
  430.    error_handler(0,"Pair is not in tree ");
  431.    st.clear();
  432.    return 0;                                         // Paar nicht im Baum
  433.   }
  434.   else
  435.   { 
  436.    if (p->blatt()) 
  437.    {
  438.     if (p==root)
  439.     {
  440.      error_handler(0,"Root is deleted.");
  441.      p=st.pop();
  442.      root=0;
  443.      anzahl=0;
  444.      return p;                                       // Wurzel geloescht
  445.     } 
  446.     else
  447.     {
  448.      delleaf(p);                                 // (x,y) steht in einem Blatt
  449.     }
  450.    }
  451.    else                                          // (x,y) steht in einem Knoten
  452.    {
  453.     p->x_val = p->y_val = 0;
  454.     fill(p);
  455.     while (!p->blatt())                               // Knoteninhalt loeschen
  456.     {                                                 // und neu auffuellen
  457.      if (cmp(x,y,p->split_value_x(),p->split_value_y())<=0) p=p->sohn[left];
  458.      else p=p->sohn[right];
  459.      st.push(p);
  460.     };
  461.     
  462.     delleaf(p);                                    // loescht zugehoeriges Blatt
  463.    }
  464.  
  465.    while (!st.empty())                                 // rebalancieren
  466.    { 
  467.     t = st.pop();
  468.     //cout << "stack\n";
  469.     //cout << t->split_value()<<":"<<t->x_value()<<":"<<t->y_value()<<"\n";
  470.     father = st.empty() ? 0 : st.top() ;
  471.     t->gr--;              
  472.     float i=t->bal();
  473.     //cout << "i :" << i << "\n";
  474.     if (i<alpha)
  475.     { 
  476.      if (t->sohn[right]->bal() <= d) lrot(t,father);
  477.      else ldrot(t,father);
  478.     }
  479.     else if (i>1-alpha)
  480.     { 
  481.      if(t->sohn[left]->bal() > d) rrot(t,father);
  482.      else rdrot(t,father);
  483.     }
  484.    }
  485.    return(deleted);
  486.   }
  487.  }
  488.    
  489. //-----------------------------------------------------------------------
  490. //enumerate(x1,x2,y0,p)
  491. //gibt alle Punkte (x,y) aus Unterbaum mit Wurzel p
  492. //mit folgender Eigenschaft an :
  493. //  x1 <= x <= x2   &&   y <= y0 
  494. //Voraussetzung : x1 < x2
  495.  
  496. void ps_tree::enumerate(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  497. {
  498.  if (cmp(y0,p->y_value())>=0 && p!=0)
  499.  {
  500.   if (cmp(x1,p->split_value_x())<=0 && cmp(p->split_value_x(),x2)<=0)
  501.   {
  502.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  503.       cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  504.    enumerate(x1,x2,y0,p->sohn[left]); 
  505.    enumerate(x1,x2,y0,p->sohn[right]); 
  506.   }
  507.   else if (cmp(p->split_value_x(),x1)<=0) 
  508.        {
  509.         if(cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  510.            cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  511.         enumerate(x1,x2,y0,p->sohn[right]);
  512.        }
  513.        else if (cmp(x2,p->split_value_x())<=0) 
  514.        {
  515.         if(cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  516.            cout <<p->split_value_x()<<"("<<p->x_value()<<","<<p->y_value()<<")\n";
  517.         enumerate(x1,x2,y0,p->sohn[left]);
  518.        }
  519.  }
  520. }
  521.        
  522. //-----------------------------------------------------------------------
  523. //void pr_ps_tree(ps_item p;int blancs)
  524. //gibt den Baum mit Wurzel p aus
  525.  
  526. void ps_tree::pr_ps_tree(ps_item p,int blancs)
  527. {
  528.  if (p==0)
  529.    { for (int j=1;j<=blancs;j++) cout << " ";
  530.      cout << "NIL\n";
  531.      return;
  532.    }
  533.  else
  534.    { pr_ps_tree(p->sohn[left],blancs+10); 
  535.      for (int j=1;j<=blancs;j++) cout << " ";
  536.      cout << "(" << p->split_value_x() << "," << p->split_value_y() << "):";
  537.      cout << "(" << p->x_value() << "," << p->y_value() << ")\n";
  538.      pr_ps_tree(p->sohn[right],blancs+10); 
  539.    }
  540. }
  541.  
  542. //-----------------------------------------------------------------------
  543. //min_x_in_rect(x1,x2,y0,p)
  544. //sucht nach Paar (x,y) im Unterbaum von p 
  545. //mit folgender Eigenschaft :
  546. //  min { x ; es gibt y, so dass x1<=x<=x2 und y<=y0 } , falls existiert,
  547. //                                                   0 , sonst.
  548.  
  549. pair_item ps_tree::min_x_in_rect(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  550. {
  551.  pair_item  c;
  552.  
  553.  if (p==0)
  554.  {
  555.   return 0;                                   // Baum ist leer.
  556.  }
  557.  else
  558.  {
  559.   c=new pair;
  560.   c->x_pkt=c->y_pkt=0;
  561.   c->valid=false;
  562.   if (cmp(y0,p->y_value())>=0)
  563.   {
  564.    if (!p->blatt())
  565.    {
  566.     if (cmp(x1,p->split_value_x())<=0) 
  567.         c=min_x_in_rect(x1,x2,y0,p->sohn[left]);
  568.     if (!c->valid && cmp(p->split_value_x(),x2)<0) 
  569.         c=min_x_in_rect(x1,x2,y0,p->sohn[right]);
  570.    }
  571.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0 
  572.        && cmp(p->y_value(),y0)<=0
  573.        && (!c->valid || cmp(p->x_value(),c->x_pkt)<0)     )
  574.    {
  575.     c->x_pkt=p->x_value();  
  576.     c->y_pkt=p->y_value();  
  577.     c->valid=true;
  578.    }
  579.   }
  580.   return c;
  581.  }
  582. }
  583.  
  584. //-----------------------------------------------------------------------
  585. //max_x_in_rect(x1,x2,y0,p)
  586. //sucht nach Paar (x,y) im Unterbaum von p 
  587. //mit folgender Eigenschaft :
  588. //  max { x ; es gibt y, so dass x1<=x<=x2 und y<=y0 } , falls existiert,
  589. //                                                   0 , sonst.
  590.  
  591. pair_item ps_tree::max_x_in_rect(x_typ x1,x_typ x2,x_typ y0,ps_item p)
  592. {
  593.  pair_item c;
  594.  
  595.  if (p==0) 
  596.  {
  597.   return 0;                                      // Baum ist leer.
  598.  }
  599.  else
  600.  {
  601.   c=new pair;
  602.   c->x_pkt=c->y_pkt=0;
  603.   c->valid=false;
  604.   if (cmp(y0,p->y_value())>=0)
  605.   {
  606.    if (!p->blatt())
  607.    {
  608.     if (cmp(p->split_value_x(),x2)<=0) 
  609.         c=max_x_in_rect(x1,x2,y0,p->sohn[right]);
  610.     if (!c->valid && cmp(x1,p->split_value_x())<0) 
  611.         c=max_x_in_rect(x1,x2,y0,p->sohn[left]);
  612.    }
  613.    if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0 
  614.        && cmp(p->y_value(),y0)<=0
  615.        && (!c->valid || cmp(p->x_value(),c->x_pkt)>0)     )
  616.    {
  617.     c->x_pkt=p->x_value();  
  618.     c->y_pkt=p->y_value();  
  619.     c->valid=true;
  620.    }
  621.   }
  622.   return c;
  623.  }
  624. }
  625.  
  626. //-----------------------------------------------------------------------
  627. //min_y_in_xrange(x1,x2,p)
  628. //sucht Paar (x,y) im Unterbaum von p
  629. //mit folgender Eigenschaft :
  630. // y = min { y ; es gibt x, so dass x1<=x<=x2 } , falls existiert,
  631. //                                            0 , sonst.
  632.  
  633. pair_item ps_tree::min_y_in_xrange(x_typ x1,x_typ x2,ps_item p)
  634. {
  635.  pair_item c1,c2;
  636.  
  637.  if (p==0)
  638.  {
  639.   return 0;                                      // Baum ist leer.
  640.  }
  641.  else
  642.  {
  643.   c1 = new pair;
  644.   c2 = new pair;
  645.   c1->x_pkt=c1->y_pkt=c2->x_pkt=c2->y_pkt=0; 
  646.   c1->valid=c2->valid=false;
  647.   if (cmp(x1,p->x_value())<=0 && cmp(p->x_value(),x2)<=0)
  648.   {
  649.    c1->x_pkt=p->x_value();
  650.    c1->y_pkt=p->y_value();
  651.    c1->valid=true;
  652.   }
  653.   else if (!p->blatt())
  654.   {
  655.    if (cmp(x1,p->split_value_x())<=0) c1=min_y_in_xrange(x1,x2,p->sohn[left]);
  656.    if (cmp(p->split_value_x(),x2)<0)  c2=min_y_in_xrange(x1,x2,p->sohn[right]);
  657.    if (!c1->valid || (c2->valid && cmp(c2->y_pkt,c1->y_pkt)<0)) c1=c2;
  658.   }
  659.   return c1;
  660.  } 
  661. }
  662.  
  663. //-----------------------------------------------------------------------
  664. // Funktion fuer Destruktor
  665. //-----------------------------------------------------------------------
  666.   
  667. void ps_tree::deltree(ps_item p)
  668. {
  669.  if (p)
  670.  {
  671.   if (!p->blatt())
  672.   {
  673.    deltree(p->sohn[left]);
  674.    deltree(p->sohn[right]);
  675.   }
  676.   delete(p);
  677.  }
  678. }
  679.