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

MultiPlatform

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