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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _iv_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. //  Interval Trees
  14. //
  15. //  Michael Seel   (1990/91)
  16. //
  17. // Implementation as described in
  18. // Kurt Mehlhorn: Data Structures and Algorithms 3, section VIII.5.1.1
  19. //
  20. // -------------------------------------------------------------------
  21. #include <LEDA/impl/iv_tree.h>
  22. // -------------------------------------------------------------
  23. // member functions von iv_tree
  24. // -------------------------------------------------------------
  25. // -------------------------------------------------------------
  26. // lrot() , rrot() , ldrot() , rdrot()
  27. // Rotationen am Knoten p
  28. void iv_tree::lrot(iv_item p, iv_item q)
  29. // p ist der zentrale Knoten um den rotiert wird
  30. // q ist der Vater von p
  31.   iv_item h = p->son[_right];
  32.   p->son[_right] = h->son[_left];
  33.   h->son[_left] = p;
  34.    
  35.   if (!q) root=h;
  36.   else
  37.   {
  38.    if ( p == q->son[_left] )   q->son[_left]=h;
  39.    else q->son[_right]=h;
  40.   }; 
  41.   
  42.   p->gr=p->son[_left]->groesse()+p->son[_right]->groesse();
  43.   h->gr=p->groesse()+h->son[_right]->groesse();
  44.   reorganize_nodelist(h,p);
  45. }
  46. void iv_tree::rrot(iv_item p, iv_item q)
  47. // p ist der zentrale Knoten um den rotiert wird
  48. // q ist der Vater von p
  49.   iv_item h = p->son[_left];
  50.   p->son[_left] = h->son[_right];
  51.   h->son[_right] = p;
  52.   if (!q) root=h;
  53.   else
  54.   {
  55.    if ( p == q->son[_left] ) q->son[_left] = h;
  56.    else q->son[_right] = h; 
  57.   };
  58.   p->gr=p->son[_left]->groesse()+p->son[_right]->groesse();
  59.   h->gr=p->groesse()+h->son[_left]->groesse();
  60.   reorganize_nodelist(h,p);
  61. }
  62. void iv_tree::ldrot(iv_item p, iv_item q)
  63.   iv_item h = p->son[_right];
  64.   //iv_item t = h->son[_left];
  65.   rrot(h,p);
  66.   lrot(p,q);
  67. }
  68. void iv_tree::rdrot(iv_item p, iv_item q)
  69. {
  70.   iv_item h = p->son[_left];
  71.   //iv_item t = h->son[_right];
  72.   lrot(h,p);
  73.   rrot(p,q);
  74. }
  75.  
  76. // ------------------------------------------------------------------
  77. // reorganize_nodelist()
  78. // reorganisiert die nach der Rotation falsch mit Intervallen belegten
  79. // Nodelists entsprechend neu.
  80. void iv_tree::reorganize_nodelist(iv_item father, iv_item son)
  81. {
  82.   // nach Aendern des Dictionary-Typs in perfekte BB_trees mit Konstruk-
  83.   // tionsprozedur, die aus einer Liste von n geordneten Knoten ein neu-
  84.   // es Dictionary in Zeit O(n) erzeugt, werden von den folgenden 4 Ite-
  85.   // rationen je 2 in ein Misch_Sort Verfahren abgeaendert und die so
  86.   // auf father und son verteilten Intervalle in Linearzeit in die Kno-
  87.   // ten dictionarys eingebunden
  88.   dic_item it;
  89.   nodelist_p fx = new nodelist;
  90.   nodelist_p fy = new nodelist;
  91.   nodelist_p sx = new nodelist;
  92.   nodelist_p sy = new nodelist;
  93.   forall_items(it,*(father->x_nodelist())) // father->x_nodelist
  94.          // liefert Pointer
  95.          // auf x-Dictionary
  96.       {
  97.  if (split_in_x_interval(father , x_nodelist(father)->key(it)))
  98.     fx->insert(x_nodelist(father)->key(it),x_nodelist(father)->inf(it));
  99.          else
  100.     sx->insert(x_nodelist(father)->key(it),x_nodelist(father)->inf(it));
  101.       };
  102.   // die x-Knotenliste des Vaters wird durchsucht und alle passenden
  103.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  104.   forall_items(it,*(son->x_nodelist())) // son->x_nodelist
  105.               // liefert Pointer
  106.             // auf x-Dictionary
  107.       {
  108.  if (split_in_x_interval(father , x_nodelist(son)->key(it))) 
  109.     fx->insert(x_nodelist(son)->key(it),x_nodelist(son)->inf(it));
  110.          else
  111.     sx->insert(x_nodelist(son)->key(it),x_nodelist(son)->inf(it));
  112.       };
  113.   // die x-Knotenliste des Sohns wird durchsucht und alle passenden
  114.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  115.   forall_items(it,*(father->y_nodelist())) // father->y_nodelist
  116.                         // liefert Pointer
  117.                // auf y-Dictionary
  118.       {
  119.  if (split_in_y_interval(father , y_nodelist(father)->key(it)))
  120.     fy->insert(y_nodelist(father)->key(it),y_nodelist(father)->inf(it));
  121.          else
  122.     sy->insert(y_nodelist(father)->key(it),y_nodelist(father)->inf(it));
  123.       };
  124.   // die y-Knotenliste des Vaters wird durchsucht und alle passenden
  125.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  126.   forall_items(it,*(son->y_nodelist())) // son->y_nodelist
  127.     // liefert Pointer
  128.     // auf y-Dictionary
  129.       {
  130.  if (split_in_y_interval(father, y_nodelist(son)->key(it)))
  131.     fy->insert(y_nodelist(son)->key(it),y_nodelist(son)->inf(it));
  132.          else
  133.     sy->insert(y_nodelist(son)->key(it),y_nodelist(son)->inf(it));
  134.       };
  135.   // die y-Knotenliste des Sohns wird durchsucht und alle passenden
  136.   // Intervalle der Vater-Knotenliste zugeordnet, Rest an den Sohn
  137.   delete x_nodelist(father);
  138.   delete y_nodelist(father);
  139.   delete x_nodelist(son);
  140.   delete y_nodelist(son);
  141.   // alte Dictionaries werden geloescht und freigegeben
  142.   father->x_nl = fx;
  143.   father->y_nl = fy;
  144.   son->x_nl = sx;
  145.   son->y_nl = sy;
  146.   // Knotenlisten werden mit neu angeordneten Dictionaries intialisiert
  147. }
  148. // ------------------------------------------------------------
  149. // search()
  150. // nachher: st = ( pk ,..., p1 ) mit 
  151. //          pk = locate(y) , p1 = root 
  152. //          p1 , ... , pk ist Suchpfad nach y
  153. // liefert inneren Knoten k mit key(k) = y , falls existiert
  154. //         0                               , sonst
  155. iv_item iv_tree::search(split_item x)
  156.   st.clear();
  157.   iv_item p = root;
  158.   iv_item searched = 0;
  159.   if (!root) return 0;         // Baum leer
  160.   while (!p->blatt())
  161.   { 
  162.     if (cmp(x,split_value(p))<=0)
  163.     {
  164.       if (cmp(x,split_value(p))==0) searched = p;
  165.       st.push(p);
  166.       p = p->son[_left];
  167.     }
  168.     else
  169.     {
  170.       st.push(p);
  171.       p = p->son[_right];
  172.     }
  173.   }
  174.   st.push(p);
  175.   return searched;
  176. }
  177. // ------------------------------------------------------------------
  178. // iv_insert(x_typ,x_typ)
  179. // fuegt ein neues Intervall (x,y) in den Baum ein
  180. // gibt Zeiger auf Knoten, in dessen Knotenliste Intervall
  181. // eingefuegt wurde, zurueck.
  182. iv_item iv_tree::iv_insert(x_typ x, x_typ y)
  183. {
  184.  if (y<x)
  185.  {
  186.   error_handler(0,"kein Intervall zum einfuegen");
  187.   return 0;
  188.  }
  189.  else
  190.  {
  191.   interval_item x_iv = new interval(x,y);
  192.   interval_item y_iv = new interval(y,x);
  193.   return ins(x_iv,y_iv,++interval_nb);
  194.  }
  195. }
  196. // ------------------------------------------------------------------
  197. // ins(interval_item,interval_item,int)
  198. // fuegt den entsprechenden Knoten in die Grundstruktur mit dem 
  199. // entsprechenden split_value und fuegt die beiden Intervalle am
  200. // entsprechenden Knoten in die Knotenlisten
  201. iv_item iv_tree::ins(interval_item x, interval_item y, int lfnr) 
  202. {
  203.  iv_item p;
  204.  iv_item t;
  205.  iv_item father;
  206.  split_pair x_pair(x->koo1,-lfnr);
  207.  split_item x_split = &x_pair; 
  208.  
  209.  if (!root)                                     // neuer Baum
  210.  { 
  211.   root = new iv_node(x_split);
  212.   anzahl=1;
  213.  }
  214.  else     // Baum existiert schon !!
  215.   if (root->blatt())
  216.   {
  217.     if (cmp(x_split,split_value(root))<0)
  218.     {
  219.      iv_item help = new iv_node(x_split);
  220.      root = new iv_node(x_split,node,help,root);
  221.      if (x_split->key1==split_value(root->son[_right])->key1)
  222.       nodelist_swap(root , root->son[_right]);
  223.      anzahl++;
  224.     }
  225.     else
  226.      if (cmp(x_split,split_value(root))>0)
  227.      {
  228.       iv_item help = new iv_node(x_split);
  229.       root = new iv_node(split_value(root),node,root,help);
  230.       nodelist_swap(root , root->son[_left]);
  231.       anzahl++;
  232.      }
  233.   }
  234.   else // in Knoten von nicht trivialem Baum wird eingefuegt
  235.   {
  236.     search(x_split);
  237.     p = st.pop();
  238.     father = st.top();
  239.   
  240.     if(cmp(x_split,split_value(p))<0)
  241.     {
  242.      iv_item help = new iv_node(x_split);
  243.      p = new iv_node(x_split,node,help,p);
  244.      // neuer Knoten in p mit split x, x-Blatt links, p-Blatt rechts
  245.      if (x_split->key1==split_value(p->son[_right])->key1)
  246.       nodelist_swap(p , p->son[_right]);
  247.      if (cmp(split_value(p),split_value(father))<=0)
  248.        father->son[_left] = p;
  249.      else
  250.        father->son[_right] = p;
  251.      anzahl++;
  252.     }
  253.     else
  254.      if (cmp(x_split,split_value(p))>0)
  255.      {           
  256.       iv_item help = new iv_node(x_split);
  257.       p = new iv_node(split_value(p),node,p,help);
  258.       // neuer Knoten in p mit split p, p-Blatt links, x-Blatt rechts
  259.       nodelist_swap(p , p->son[_left]);
  260.       if (cmp(split_value(p),split_value(father))<=0)
  261.         father->son[_left] = p;
  262.       else
  263.         father->son[_right] = p;
  264.       anzahl++;
  265.      }
  266.   }
  267.   while (!st.empty())                          // rebalancieren
  268.   { 
  269.     t=st.pop();
  270.     father = st.empty() ? 0 : st.top();
  271.     t->gr++;  
  272.     float i = t->bal();
  273.     if (i < alpha)
  274.     {
  275.      if (t->son[_right]->bal()<=d)
  276.        lrot(t,father);
  277.      else
  278.        ldrot(t,father);
  279.     }
  280.     else
  281.     if (i>1-alpha) 
  282.     {
  283.       if (t->son[_left]->bal()>d)
  284. rrot(t,father);
  285.       else
  286. rdrot(t,father);
  287.     }
  288.   }
  289.   
  290.   p = sink(root,x,y,lfnr);
  291.   return p;
  292. }
  293. // ------------------------------------------------------------------
  294. // sink()
  295. // laesst Intervall im Baum bis zu dem Knoten v abwaerts gleiten an dem 
  296. // gilt: 1.Komponente von split_value(v) <in> Intervall <Teilmenge von> x_range(v)
  297. iv_item iv_tree::sink(iv_item v, interval_item x, interval_item y, int lfnr)
  298. {
  299.    if (v)
  300.    {
  301.      if (split_in_x_interval(v,x))
  302.      {
  303.        if (x_nodelist(v)->lookup(x))
  304.        {
  305.          error_handler(0,"Interval wurde schon eingefuegt!n");
  306.  split_pair h(x->koo1,-lfnr);
  307.  split_item hi=&h;
  308.  del(hi);
  309.  return 0;
  310.        }
  311.        x_nodelist(v)->insert(x,lfnr);
  312.        y_nodelist(v)->insert(y,lfnr);
  313.        return v;
  314.      }
  315.      else
  316.      {
  317.        if (x->cmp(x->koo2,split_value(v)->key1) < 0)
  318.        { 
  319.  return sink(v->son[_left],x,y,lfnr);
  320.        }
  321.        else
  322.        if (x->cmp(split_value(v)->key1,x->koo1) < 0)
  323.        {
  324.  return sink(v->son[_right],x,y,lfnr);
  325.        }
  326.      }
  327.    }
  328.    return 0;
  329. }
  330. // ------------------------------------------------------------------
  331. // iv_delete(x_typ,x_typ)
  332. // loescht ein Intervall (x,y) aus dem Baum
  333. // gibt Zeiger auf geloeschtes intervall zurueck 
  334. void iv_tree::iv_delete(x_typ x, x_typ y)
  335. {
  336.   if (y<x) 
  337.   {
  338.    error_handler(0,"kein Intervall!n");
  339.    return;
  340.   }
  341.   else
  342.   if (!root) error_handler(0,"Baum ist leer!n");
  343.   else
  344.   {
  345.    iv_item v = root;
  346.    interval xi(x,y);
  347.    interval yi(y,x);
  348.    interval_item x_iv = &xi;
  349.    interval_item y_iv = &yi; 
  350.    while ( !split_in_x_interval(v,x_iv) && !v->blatt() )
  351.    {
  352.     if (split_value(v)->cmp(y,split_value(v)->key1) < 0)
  353.     {
  354.       v = v->son[_left];
  355.     }
  356.     if (split_value(v)->cmp(split_value(v)->key1,x) < 0) 
  357.     {
  358.       v = v->son[_right];
  359.     }
  360.    }
  361.    // nun ist v der Knoten an dem das Intervall [x,y] abgespeichert sein muesste
  362.    dic_item help1 = x_nodelist(v)->lookup(x_iv);
  363.    dic_item help2 = y_nodelist(v)->lookup(y_iv);
  364.    if (!(help1 && help2))
  365.    {
  366.     error_handler(0,"Intervall nicht vorhanden!n");
  367.     return;
  368.    }
  369.    else
  370.    {
  371.     split_pair s(x_nodelist(v)->key(help1)->koo1,-x_nodelist(v)->inf(help1));
  372.     split_item search_split = &s; 
  373.     x_nodelist(v)->del_item(help1);
  374.     y_nodelist(v)->del_item(help2);
  375.     if (!del(search_split)) 
  376.       error_handler(1,"Intervall geloescht, Grundstruktur nicht in Ordnungn");
  377.    } 
  378.   }
  379. }
  380. // ------------------------------------------------------------------
  381. // del()
  382. // loescht Item it im Baum mit split(it)=y , falls existiert
  383. // gibt 1 zurueck, falls existent und geloescht
  384. // gibt 0 zurueck, falls nicht existent
  385. int iv_tree::del(split_item y)
  386. {
  387.   st.clear();
  388.   if (root==0) return 0;                         // s.n.
  389.   if (root->blatt())                             // Wurzel loeschen
  390.     if (cmp(y,split_value(root))==0)
  391.     { 
  392.       if (!x_nodelist(root)->empty()) 
  393.  error_handler(1,"noch Intervalle in zu loeschender Wurzel!n");
  394.       anzahl=0; 
  395.       delete root;
  396.       root=0; 
  397.       return 1; 
  398.     }
  399.     else
  400.     {
  401.      error_handler(0,"Element nicht im Baumn");  
  402.      return 0;
  403.     }
  404.   else // Baum nicht trivial
  405.   {
  406.     iv_item p,father;
  407.     iv_item pp=search(y);
  408.     if (st.size()==2)                            // Sohn der Wurzel
  409.     { 
  410.       p=st.pop();
  411.       father=st.pop();
  412.       int v1 = cmp(y,split_value(father));
  413.       if (cmp(y,split_value(p))!=0)
  414.       {
  415.         return 0;
  416.       }
  417.       anzahl--;
  418.       if (v1<=0)
  419.       {
  420.         root=root->son[_right];
  421. if(!x_nodelist(father)->empty())
  422.   nodelist_swap(father,root);
  423.       }
  424.       else
  425.       {
  426.         root=root->son[_left];
  427. if(!x_nodelist(father)->empty())
  428.   {
  429.     if (!root->son[_right]) 
  430.        nodelist_swap(father,root);
  431.             else
  432.     if ((root->son[_right])&&(x_nodelist(father)->size()==2))
  433.             {
  434.        nodelist_swap(father,root->son[_right]);
  435.        reorganize_nodelist(root,root->son[_right]);
  436.             }
  437.             else
  438.        nodelist_swap(father,root->son[_right]);
  439.           } 
  440.       }
  441.       if (!x_nodelist(father)->empty() || !x_nodelist(p)->empty())
  442. error_handler(1,"Knotenlisten beim Loeschen nicht leern");
  443.       delete father;
  444.       delete p;
  445.     }
  446.     else                                // Blatt mit Tiefe >= 2     
  447.     {
  448.       iv_item p=st.pop();
  449.       if (cmp(y,split_value(p))!=0)
  450.       { 
  451. return 0;
  452.       }
  453.       iv_item q = st.pop();
  454.       father = st.top();
  455.       int v1 = cmp(y,split_value(father));
  456.       int v2 = cmp(y,split_value(q));
  457.       anzahl--;
  458.       if (v1<=0)
  459.         if (v2<=0)
  460. {
  461.   father->son[_left]=q->son[_right];
  462.   if(!x_nodelist(q)->empty())
  463.     nodelist_swap(q,father->son[_right]);
  464.         }
  465.         else
  466. {
  467.   father->son[_left]=q->son[_left];
  468.   if(!x_nodelist(q)->empty())
  469.   {
  470.     if (!father->son[_left]->son[_right])
  471.        nodelist_swap(q,father->son[_left]);
  472.             else
  473.     if ((father->son[_left]->son[_right])&&(x_nodelist(q)->size()==2))
  474.             {
  475.        nodelist_swap(q,father->son[_left]->son[_right]);
  476.        reorganize_nodelist(father->son[_left],father->son[_left]->son[_right]);
  477.             }
  478.             else
  479.        nodelist_swap(q,father->son[_left]->son[_right]);
  480.           } 
  481.         }
  482.       else
  483. if (v2<=0)
  484. {
  485.   father->son[_right]=q->son[_right];
  486.   if(!x_nodelist(q)->empty())
  487.     nodelist_swap(q,father->son[_right]);
  488.         }
  489.         else
  490. {
  491.   father->son[_right]=q->son[_left];
  492.   if(!x_nodelist(q)->empty())
  493.   {
  494.     if (!father->son[_right]->son[_right])
  495.        nodelist_swap(q,father->son[_right]);
  496.             else
  497.     if ((father->son[_right]->son[_right])&&(x_nodelist(q)->size()==2))
  498.             {
  499.        nodelist_swap(q,father->son[_right]->son[_right]);
  500.        reorganize_nodelist(father->son[_right],father->son[_right]->son[_right]);
  501.             }
  502.             else
  503.        nodelist_swap(q,father->son[_right]->son[_right]);
  504.           } 
  505.         }
  506.       if (!x_nodelist(p)->empty())
  507. error_handler(1,"Knotenlisten von p beim Loeschen nicht leer");
  508.       delete p;
  509.       delete q;
  510.     }
  511.   }
  512.   
  513.   // REBALANCIEREN
  514.   iv_item p;
  515.   iv_item father;
  516.   while (!st.empty())
  517.   { p = st.pop();
  518.     father = st.empty() ? 0 : st.top() ;
  519.     p->gr--;              
  520.     float i=p->bal();
  521.     if (i<alpha)
  522.       if (p->son[_right]->bal() <= d)
  523.        lrot(p,father);
  524.       else
  525.        ldrot(p,father);
  526.     else
  527.     if (i>1-alpha)
  528.       if(p->son[_left]->bal() > d)
  529.        rrot(p,father);
  530.       else
  531.        rdrot(p,father);
  532.   }
  533.   return 1;
  534. }
  535. // ------------------------------------------------------------------
  536. // iv_query(x_typ,x_typ)
  537. // gibt alle Intervalle in einer Liste zurueck, die das mit 
  538. // den Parametern uebergebene Intervall schneiden.
  539. interval_list iv_tree::iv_query(x_typ x, x_typ y)
  540. {
  541.  interval_list query_list;
  542.  if (!root)
  543.  {
  544.    error_handler(0,"Baum ist leer");
  545.    return query_list;
  546.  } 
  547.  if (y<x)
  548.  { 
  549.   error_handler(0,"kein Intervalln");
  550.   return query_list;
  551.  }
  552.  split_pair xp(x,-MAXINT);
  553.  split_pair yp(y,MAXINT);
  554.  split_item xi = &xp;
  555.  split_item yi = &yp;
  556.  iv_item v = root;
  557.  int done=0;
  558.  // Bestimmung der P-Menge mit Hilfe von search-Schleife nach x,
  559.  // unterwegs Abzweig zu search nach y
  560.  // alle zwischen den Pfaden liegenden Knoten werden mit get_all
  561.  // abgearbeitet
  562.  // jeder Knoten wird mit Hilfe von check_iv() nach den in den 
  563.  // Knotenmengen vorhandenen Intervallen, die die Schnittbegingung
  564.  // erfuellen abgearbeitet.
  565.  while (!v->blatt())
  566.  {
  567.    check_nodelist(query_list,v,x,y);
  568.    if (cmp(xi,split_value(v))<=0) // xi <= split(v)
  569.    {
  570.      if ((cmp(yi,split_value(v))>0) && !done)
  571.      {
  572.        y_search(query_list,v->son[_right],yi,x,y);
  573.        done=1;
  574.      }
  575.      else
  576.      {
  577.        if (done)  // klappert den gesamten Unterbaum von v der C-Menge ab
  578.          get_all_in_tree(query_list,v->son[_right]);
  579.      }
  580.      v=v->son[_left];
  581.    }
  582.    else  // xi > split(v)
  583.    {
  584.      v=v->son[_right];
  585.    }
  586.  }
  587.  check_nodelist(query_list,v,x,y);
  588.  return query_list;
  589. }
  590. // ------------------------------------------------------------------
  591. // y_search()
  592. // verzweigt vom Knoten v aus, in einen neuen Suchpfad nach dem y-
  593. // Wert des query-Intervalls und fuehrt auch dort die P-checks durch
  594. void iv_tree::y_search(interval_list& il, iv_item v, split_item ys,
  595.        x_typ x, x_typ y)
  596. {
  597.  while (!v->blatt())
  598.  {
  599.    check_nodelist(il,v,x,y);
  600.    if (cmp(ys,split_value(v))<=0) // ys <= split(v)
  601.      v=v->son[_left];
  602.    else  // ys > split(v)
  603.    {
  604.      get_all_in_tree(il,v->son[_left]);
  605.      // klappert den gesamten Unterbaum von v der C-Menge ab
  606.      v=v->son[_right];
  607.    }
  608.  }
  609.  check_nodelist(il,v,x,y);
  610. }
  611.   
  612. // ------------------------------------------------------------------
  613. // check_nodelist()
  614. // ueberprueft entsprechend der in MEHLHORN III dargestellten Fall-
  615. // unterscheidung fuer P-Knoten die jeweilige x- oder y-Knotenliste
  616. // oder uebernimmt alle Eintraege.
  617. void iv_tree::check_nodelist(interval_list& il, iv_item v, x_typ x, x_typ y)
  618. {
  619.   if ((split_value(v)->cmp(x,split_value(v)->key1)<=0)
  620.   && (split_value(v)->cmp(split_value(v)->key1,y)<=0))
  621.   // dann ist split(v) im query-Intervall, das damit alle Intervalle
  622.   // der Knotenliste schneidet.
  623.     take_all_iv(il,v);
  624.   else
  625.   if (split_value(v)->cmp(x,split_value(v)->key1)>0)
  626.   // Intervall oberhalb des split(v)
  627.     check_y_iv(il,v,x);
  628.   else
  629.   // Intervall unterhalb des split(v)
  630.     check_x_iv(il,v,y);
  631. }
  632. // ------------------------------------------------------------------
  633. // get_all_in_tree()
  634. // uebernimmt alle im Unterbaum des Knotens v abgespeicherten Inter-
  635. // valle in die uebergebene Liste
  636. // entspricht einer Teilmenge der C-Menge
  637. void iv_tree::get_all_in_tree(interval_list& il, iv_item v)
  638. {
  639.   take_all_iv(il,v);
  640.   if (!v->blatt())
  641.   { 
  642.     get_all_in_tree(il,v->son[_left]);
  643.     get_all_in_tree(il,v->son[_right]);
  644.   }
  645. }
  646. // ------------------------------------------------------------------
  647. // take_all_iv()
  648. // uebernimmt an einem Knoten alle abgespeicherten Intervalle
  649. // in die mituebergebene Liste.
  650. void iv_tree::take_all_iv(interval_list& il, iv_item v)
  651. {
  652.   dic_item it;
  653.   forall_items(it,*(v->x_nodelist()))
  654.   {
  655.     interval_item help = x_nodelist(v)->key(it);
  656.     interval_item ii = new interval(help->koo1, help->koo2);
  657.     il.append(ii);
  658.   }
  659. }
  660. // ------------------------------------------------------------------
  661. // check_y_iv()
  662. // ueberprueft an einem Knoten alle Intervalle der y-Knotenliste
  663. // auf Schnittbedingung mit dem uebergebenen x-Wert des query-
  664. // Intervalls und haengt bei erfuellter Schnittbedingung das In-
  665. // tervall an die mituebergebene Liste an.
  666.   void iv_tree::check_y_iv(interval_list& il, iv_item v, x_typ x)
  667.   { 
  668.       if (!y_nodelist(v)->empty())
  669.       {
  670. dic_item maxit = y_nodelist(v)->max();
  671. if (split_value(v)->cmp(y_nodelist(v)->key(maxit)->koo1,x)>=0) 
  672. {
  673.   dic_item it = maxit;
  674.   int intersect = 1;
  675.   while(it && intersect) 
  676.   {
  677.     if (split_value(v)->cmp(y_nodelist(v)->key(it)->koo1,x)>=0) 
  678.     {
  679.      interval_item help = y_nodelist(v)->key(it); 
  680.      interval_item ii = new interval(help->koo2, help->koo1);
  681.      // die Intervalle der y-Knotenliste haben 1. Komponente
  682.      // y und 2. Komponente x, zur Rueckgabe ist aber die
  683.      // umgekehrte Reihenfolge verlangt.
  684.      il.append(ii);
  685.     }
  686.     else
  687.      intersect = 0;
  688.     it = y_nodelist(v)->pred(it);
  689.           }
  690.         }
  691.       }
  692.   }
  693. // ------------------------------------------------------------------
  694. // check_x_iv()
  695. // ueberprueft an einem Knoten alle Intervalle der x-Knotenliste
  696. // auf Schnittbedingung mit dem uebergebenen y-Wert des query-
  697. // Intervalls und haengt bei erfuellter Schnittbedingung das In-
  698. // tervall an die mituebergebene Liste an.
  699.   void iv_tree::check_x_iv(interval_list& il, iv_item v, x_typ y)
  700.   { 
  701.       if (!x_nodelist(v)->empty())
  702.       {
  703. dic_item minit = x_nodelist(v)->min();
  704. if (split_value(v)->cmp(x_nodelist(v)->key(minit)->koo1,y)<=0) 
  705. {
  706.   dic_item it = minit; 
  707.   int intersect = 1;
  708.   while(it && intersect) 
  709.   {
  710.     if (split_value(v)->cmp(x_nodelist(v)->key(it)->koo1,y)<=0) 
  711.     {
  712.      interval_item help = x_nodelist(v)->key(it); 
  713.      interval_item ii = new interval(help->koo1, help->koo2);
  714.      // die Intervalle der x-Knotenliste haben 1. Komponente
  715.      // x und 2. Komponente y.
  716.      il.append(ii);
  717.     }
  718.     else
  719.      intersect = 0;
  720.     it = x_nodelist(v)->succ(it);
  721.           }
  722.         }
  723.       }
  724.   }
  725. //-----------------------------------------------------------------------
  726. // void print_split(iv_item) 
  727. // gibt split_value von p aus
  728.   void iv_tree::print_split(iv_item it)   
  729.   { 
  730.     if (it)
  731.       { it->split_value()->print();
  732.         if (it->blatt()) text(" (blatt)n");
  733.         else text("(Knoten)n");
  734.        }
  735.     else
  736.       cout << " Knoten leer!n";
  737.   }
  738. //-----------------------------------------------------------------------
  739. // void pr_iv_tree(iv_item p;int blancs)
  740. // gibt den Baum mit Wurzel p aus
  741. void iv_tree::pr_iv_tree(iv_item p,int blancs)
  742. {
  743.  if (p==0)
  744.  {
  745.   for (int j=1;j<=blancs;j++) cout << " ";
  746.   cout << "NILn";
  747.   return;
  748.  }
  749.  else
  750.  {
  751.   pr_iv_tree(p->son[_left],blancs+10); 
  752.   for (int j=1;j<=blancs;j++) cout << " ";
  753.   
  754.   cout << "(" << p->split_value()->key1 << "," << p->split_value()->key2;
  755.   cout << ") ";
  756.   pr_iv_list(p);
  757.   pr_iv_tree(p->son[_right],blancs+10); 
  758.  }
  759. }
  760.  
  761. //-----------------------------------------------------------------------
  762. // void pr_iv_list(iv_item p)
  763. // gibt die Intervalliste eines Knotens p aus
  764. void iv_tree::pr_iv_list(iv_item p)
  765. {
  766.   dic_item it;
  767.   forall_items(it,*(p->x_nodelist()))
  768.   { cout << "[" << x_nodelist(p)->key(it)->koo1;
  769.     cout << "," << x_nodelist(p)->key(it)->koo2 << "]"; 
  770.     cout << "#" << x_nodelist(p)->inf(it) << ";";
  771.    }
  772.   cout << "  *  ";
  773.   forall_items(it,*(p->y_nodelist()))
  774.   { cout << "[" << y_nodelist(p)->key(it)->koo1;
  775.     cout << "," << y_nodelist(p)->key(it)->koo2<< "]"; 
  776.     cout << "#" << y_nodelist(p)->inf(it) << ";";
  777.    }
  778.   cout << "n";
  779. }
  780. //-----------------------------------------------------------------------
  781. // void pr_list()
  782. // gibt die zurueckgegebene Intervalliste der query aus
  783. void iv_tree::pr_list(interval_list& il)
  784. {
  785.   cout << "Liste: n";
  786.   if(il.empty()) cout << " leern";
  787.   list_item it;
  788.   forall_list_items(it,il)
  789.     il.contents(it)->print(); 
  790. }
  791.     
  792. //-----------------------------------------------------------------------
  793. // Funktion fuer Destruktor
  794. //-----------------------------------------------------------------------
  795.   
  796. void iv_tree::deltree(iv_item p)
  797. {
  798.  if (p)
  799.  {
  800.   if (!p->blatt())
  801.   {
  802.    deltree(p->son[_left]);
  803.    deltree(p->son[_right]);
  804.   }
  805.   delete(p);
  806.  }
  807. }