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

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _range_tree.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.  
  16. // ------------------------------------------------------------------
  17. //
  18. // d-dimensional Range Trees
  19. //
  20. // Michael Wenzel     (1990)
  21. //
  22. // Implementation follows
  23. // Data Structure Lecture, K. Mehlhorn, Summer 1989
  24. // K. Mehlhorn: Data Structures and Algorithms, Vol. 3
  25. //
  26. // ------------------------------------------------------------------
  27.  
  28. #include <LEDA/range_tree.h>
  29.  
  30. enum left_or_right {left = 0, right = 1};
  31.  
  32. #undef TEST
  33. #undef DUMP
  34. #undef STAT
  35.  
  36. #ifdef TEST
  37. #define DPRINT(x) cout << x
  38. #else
  39. #define DPRINT(x)
  40. #endif
  41.  
  42. #ifdef DUMP
  43. #define DDUMP(x) cout << x
  44. #else
  45. #define DDUMP(x)
  46. #endif
  47.  
  48. #ifdef STAT
  49. #define DSTAT print_statistics() 
  50. #else
  51. #define DSTAT
  52. #endif
  53.  
  54. //------------------------------------------------------------------
  55. // member-functions of class tuple
  56. //
  57. // Michael Wenzel          (1990)
  58. //------------------------------------------------------------------
  59.  
  60.   tuple::tuple()
  61.       { 
  62.     d=0;
  63.     t=0; }
  64.  
  65.   tuple::tuple(ent a, ent b)
  66.       { 
  67.     d=2;
  68.     t=new ent[2]; 
  69.         t[0] = a;
  70.         t[1] = b; }
  71.  
  72.   tuple::tuple(ent a, ent b, ent c)
  73.       { 
  74.     d=3;
  75.     t=new ent[3]; 
  76.         t[0] = a;
  77.         t[1] = b;  
  78.         t[2] = c;  }
  79.  
  80.   tuple::tuple(int dim)
  81.       { 
  82.     d=dim;
  83.         inf = 0;
  84.     t=new ent[dim]; }
  85.  
  86.   tuple::~tuple()
  87.       { if (t)
  88.           delete t;
  89.       }
  90.  
  91. //-------------------------------------------------------------------
  92. //  RANGE TREE
  93. //-------------------------------------------------------------------
  94.  
  95.  
  96. int range_tree::tuple_cmp(tuplep p, tuplep q)
  97. {  int i = p->cmp_dim();
  98.    int stop = (i==0) ? p->d-1 : i-1;
  99.    int res;
  100.    while ((res=cmp_tuple_entry(i,p,q))==0 && i!=stop) 
  101.      i=(i+1)%p->d;
  102.    return res;
  103. }
  104.     
  105. // ------------------------------------------------------------
  106. // lrot() , rrot() , ldrot() , rdrot()
  107. // Rotationen am Knoten p
  108.  
  109. void range_tree::lrot(bb_item p, bb_item q)
  110. {
  111.   bb_item h = p->sohn[right];
  112.   int help_dim = key(h)->cmp_dim();
  113.   key(h)->set_cmp(key(h)->dimension()-dim+1);
  114.  
  115.   DDUMP("lrot "<< (int)key(p)) ; 
  116.     if (q) DDUMP(" Vater " << (int)(key(q)));
  117.   DDUMP("\n");
  118.  
  119.   p->sohn[right] = h->sohn[left];
  120.   h->sohn[left] = p;
  121.   if (!q)
  122.     root=h;
  123.   else
  124.   { if (tuple_cmp(key(h),key(q))>0)
  125.       q->sohn[right]=h;
  126.     else
  127.       q->sohn[left]=h;
  128.   }
  129.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  130.   h->gr=p->groesse()+h->sohn[right]->groesse();
  131.  
  132.                         // update nodelists
  133.   list(range_tree_item) L;
  134.   range_tree_item x;
  135.  
  136.   bb_item s = p->sohn[left];
  137.   if (s->blatt())
  138.     inf(h)->insert_tuple(key(s));
  139.   else
  140.   { L = inf(s)->all_tuples();
  141.     forall(x,L) inf(h)->insert_tuple(x);
  142.     L.clear();
  143.   }
  144.  
  145.   s = h->sohn[right];
  146.   if (s->blatt())
  147.     inf(h)->del_tuple(key(s));
  148.   else
  149.   { L = inf(s)->all_tuples();
  150.     forall(x,L) inf(p)->del_tuple(x);
  151.   }
  152.  
  153.   key(h)->set_cmp(help_dim);
  154. }
  155.  
  156. void range_tree::rrot(bb_item p, bb_item q)
  157. {
  158.   bb_item h = p->sohn[left];
  159.   int help_dim = key(h)->cmp_dim();
  160.   key(h)->set_cmp(key(h)->dimension()-dim+1);
  161.  
  162.   DDUMP("rrot "<< (int)(key(p))) ; 
  163.     if (q) DDUMP(" Vater " << (int)(key(q)));
  164.   DDUMP("\n");
  165.  
  166.   p->sohn[left] = h->sohn[right];
  167.   h->sohn[right] = p;
  168.   if (!q) root=h;
  169.   else
  170.   { if (tuple_cmp(key(h),key(q))>0)
  171.       q->sohn[right] = h;
  172.     else
  173.       q->sohn[left] = h; }
  174.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  175.   h->gr=p->groesse()+h->sohn[left]->groesse();
  176.  
  177.                         // update nodelists
  178.   list(range_tree_item) L;
  179.   range_tree_item x;
  180.   bb_item s = p->sohn[right];
  181.   if (s->blatt())
  182.     inf(h)->insert_tuple(key(s));
  183.   else
  184.   { L = inf(s)->all_tuples();
  185.     forall(x,L) inf(h)->insert_tuple(x);
  186.     L.clear();
  187.   }
  188.  
  189.   s = h->sohn[left];
  190.   if (s->blatt())
  191.     inf(p)->del_tuple(key(s));
  192.   else
  193.   { L = inf(s)->all_tuples();
  194.     forall(x,L) inf(p)->del_tuple(x);
  195.   }
  196.   key(h)->set_cmp(help_dim);
  197. }
  198.  
  199. void range_tree::ldrot(bb_item p, bb_item q)
  200. {
  201.   bb_item h = p->sohn[right];
  202.   bb_item g = h->sohn[left];
  203.   int help_dim = key(h)->cmp_dim();
  204.   key(h)->set_cmp(key(h)->dimension()-dim+1);
  205.  
  206.   DDUMP("ldrot "<< (int)(key(p))) ; 
  207.     if (q) DDUMP(" Vater " << (int)(key(q)));
  208.   DDUMP("\n");
  209.  
  210.   p->sohn[right] = g->sohn[left];
  211.   h->sohn[left] =  g->sohn[right];
  212.   g->sohn[left] = p;
  213.   g->sohn[right] = h;
  214.   if (!q) root=g;
  215.   else
  216.   { if (tuple_cmp(key(h),key(q))>0)
  217.       q->sohn[right] =g ;
  218.     else 
  219.       q->sohn[left] = g ; }
  220.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  221.   h->gr=h->sohn[left]->groesse()+h->sohn[right]->groesse();
  222.   g->gr=p->groesse()+h->groesse();
  223.                         // update nodelists
  224.   list(range_tree_item) L;
  225.   range_tree_item x;
  226.   range_tree* help = (range_tree*)g->inf;
  227.  
  228.   g->inf = p->inf;
  229.  
  230.   bb_item s = p->sohn[right];
  231.   if (s->blatt())
  232.     inf(h)->del_tuple(key(s));
  233.   else
  234.   { L = inf(s)->all_tuples();
  235.     forall(x,L) inf(h)->del_tuple(x);
  236.     L.clear();
  237.   }
  238.  
  239.   s = h->sohn[left];
  240.   if (s->blatt())
  241.     help->del_tuple(key(s));
  242.   else
  243.   { L = inf(s)->all_tuples();
  244.     forall(x,L) help->del_tuple(x);
  245.     L.clear();
  246.   }
  247.  
  248.   s = p->sohn[left];
  249.   if (s->blatt())
  250.     help->insert_tuple(key(s));
  251.   else
  252.   { L = inf(s)->all_tuples();
  253.     forall(x,L) help->insert_tuple(x);
  254.   }
  255.  
  256.   p->inf = (ent) help;
  257.   key(h)->set_cmp(help_dim);
  258. }
  259.  
  260. void range_tree::rdrot(bb_item p, bb_item q)
  261.  
  262. {
  263.   bb_item h = p->sohn[left];
  264.   bb_item g = h->sohn[right];
  265.   int help_dim = key(h)->cmp_dim();
  266.   key(h)->set_cmp(key(h)->dimension()-dim+1);
  267.  
  268.   DDUMP("rdrot "<< (int)(key(p))) ; 
  269.     if (q) DDUMP(" Vater " << (int)(key(q)));
  270.   DDUMP("\n");
  271.  
  272.   p->sohn[left] = g->sohn[right];
  273.   h->sohn[right] =  g->sohn[left];
  274.   g->sohn[right] = p;
  275.   g->sohn[left] = h;
  276.   if (!q) root=g;
  277.   else
  278.   { if (tuple_cmp(key(h),key(q))>0)
  279.       q->sohn[right] =g ;
  280.     else 
  281.       q->sohn[left] = g ; }
  282.   p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  283.   h->gr=h->sohn[left]->groesse()+h->sohn[right]->groesse();
  284.   g->gr=p->groesse()+h->groesse();
  285.                         // update nodelists
  286.   list(range_tree_item) L;
  287.   range_tree_item x;
  288.   range_tree* help = (range_tree*)g->inf;
  289.  
  290.   g->inf = p->inf;
  291.  
  292.   bb_item s = p->sohn[left];
  293.   if (s->blatt())
  294.     inf(h)->del_tuple(key(s));
  295.   else
  296.   { L = inf(s)->all_tuples();
  297.     forall(x,L) inf(h)->del_tuple(x);
  298.     L.clear();
  299.   }
  300.  
  301.   s = h->sohn[right];
  302.   if (s->blatt())
  303.     help->del_tuple(key(s));
  304.   else
  305.   { L = inf(s)->all_tuples();
  306.     forall(x,L) help->del_tuple(x);
  307.     L.clear();
  308.   }
  309.  
  310.   s = p->sohn[right];
  311.   if (s->blatt())
  312.     help->insert_tuple(key(s));
  313.   else
  314.   { L = inf(s)->all_tuples();
  315.     forall(x,L) help->insert_tuple(x);
  316.   }
  317.  
  318.   p->inf = (ent) help;
  319.   key(h)->set_cmp(help_dim);
  320. }
  321.  
  322. // ------------------------------------------------------------
  323. // check(x,y,z)                              
  324. // check if a tuple x lies between y and z
  325. // some coordinates are already checked
  326.  
  327. bool range_tree::check(tuplep x, tuplep y, tuplep z)
  328.  
  329. { bool found=true;
  330.   int help_dim = x->cmp_dim();
  331.  
  332.   for (int i=x->dimension()-dim+1;i<=x->dimension();i++)
  333.   { x->set_cmp(i);
  334.     if ((tuple_cmp(x,y)<0)||(tuple_cmp(x,z)>0)) 
  335.     { x->set_cmp(help_dim);
  336.       return false;
  337.     }
  338.   }
  339.   x->set_cmp(help_dim);
  340.   return found;
  341. }
  342.  
  343.  
  344. //-------------------------------------------------------------------
  345. // insert_tuple
  346. // insert a tuple into a range_tree:             
  347. // - insert tuple according to first coordinate in main tree (bb-alpha)
  348. // - insert tuple according to second coordinate in all nodetrees
  349. //   on the path of the main tree from the root to the tuple
  350.  
  351. range_tree_item range_tree::insert_tuple(tuple* x)
  352.  
  353. { bb_tree_item inserted;
  354.   tuplep y;
  355.   int help_dim = x->cmp_dim();
  356.   x->set_cmp(x->dimension()-dim+1);
  357.  
  358.   DPRINT("insert tuple " << (int)x << " in "  << dim << " dimension ") ;
  359.   DPRINT("and comparedimension " << x->cmp_dim() << "\n");
  360.  
  361.   if (inserted=rm_tree::lookup(x)) 
  362.   { 
  363.     tuplep y=key(inserted);
  364.     clear_inf((ent&)y);                 // clear tuple and change inf
  365.     y->info() = x->info();
  366.     copy_inf((ent&)y);
  367.     clear_tuple(x);
  368.     delete x;
  369.  
  370.     return y;
  371.   }
  372.  
  373.   if (dim==1) 
  374.   { bb_tree_item t,father;
  375.     inserted = sinsert(x,0);
  376.  
  377.     if (!st.empty())
  378.       st.pop();                       // pop father of leaf
  379.   
  380.                                       // rebalancieren
  381.     while (!st.empty())
  382.     { t=st.pop();
  383.       father = st.empty() ? 0 : st.top();
  384.       t->gr++;  
  385.       float i = t->bal();
  386.  
  387.       DDUMP("rebal cur=" << (int)(key(t)) << " groesse= " << t->groesse() << " bal= " << i << " in Dimension 1\n");
  388.  
  389.       tuplep help = key(t);
  390.       int help_dimt = help->cmp_dim();
  391.       help->set_cmp(help->dimension());
  392.       if (i < alpha)
  393.         if (t->sohn[right]->bal()<=d) bb_tree::lrot(t,father);
  394.         else bb_tree::ldrot(t,father);
  395.       else if (i>1-alpha) 
  396.              if (t->sohn[left]->bal() > d ) bb_tree::rrot(t,father);
  397.          else bb_tree::rdrot(t,father);
  398.       help->set_cmp(help_dimt);
  399.     }
  400.     x->set_cmp(help_dim);
  401.  
  402.     return key(inserted);
  403.   }
  404.  
  405.   else
  406.   { bb_tree_item it,it1;                
  407.     range_tree*  t = new_range_tree(dim-1);
  408.  
  409.     it = sinsert(x,t);
  410.     inserted = it ;
  411.     DDUMP(" bei leerem Baum ");
  412.     t->insert_tuple(x);
  413.                                           // rebalance tree and insert 
  414.                       // tuple into nodelists  
  415.  
  416.     if (!st.empty())                     // insert correct tuple
  417.     { it1=st.pop();                      // node needs no rebalancing
  418.       DDUMP("bei " << (int)(key(it1)) << " " );
  419.       if (it==bb_tree::max())
  420.       { inf(it1)->insert_tuple(x);     
  421.         x->set_cmp(x->dimension()-dim+1);
  422.       }
  423.       else
  424.       { y= key(succ(it));
  425.     inf(it1)->insert_tuple(y);
  426.         y->set_cmp(y->dimension()-dim+1);
  427.       }
  428.     }
  429.  
  430.     while (!st.empty())
  431.     { it=st.pop();
  432.       DDUMP("bei " << (int)(key(it)) << " " );
  433.       inf(it)->insert_tuple(x);
  434.       it1 = st.empty() ? 0 : st.top();
  435.       it->gr++;  
  436.       float i = it->bal();
  437.       DDUMP("rebal cur=" << (int)(key(it)) << " groesse= " << it->groesse() << " bal= " << i << " in dimension " << dim  << "\n");
  438.  
  439.       if (i < alpha)
  440.     if (it->sohn[right]->bal()<=d) lrot(it,it1); 
  441.     else ldrot(it,it1); 
  442.       else if (i>1-alpha) 
  443.              if (it->sohn[left]->bal() > d ) rrot(it,it1);
  444.          else rdrot(it,it1);
  445.     }
  446.     x->set_cmp(help_dim);
  447.     return key(inserted);
  448.   }
  449. }
  450.  
  451. //-------------------------------------------------------------------
  452. // delete
  453. // delete a tuple in a range_tree:
  454. // - delete tuple in all nodetrees on the path of the main tree
  455. //   from the root to the tuple
  456. // - delete tuple in main tree
  457.  
  458. void range_tree::del(tuplep x)
  459.  
  460.   tuplep y = del_tuple(x);
  461.   if (y)
  462.   { clear_tuple(y);
  463.     delete y;
  464.   }
  465. }
  466.  
  467. tuplep range_tree::del_tuple(tuplep x)
  468.  
  469. {
  470.   DPRINT("delete tuple " << (int)x << " in "  << dim << " dimension\n");
  471.  
  472.   tuplep deleted;
  473.   int help_dim = x->cmp_dim();
  474.   x->set_cmp(x->dimension()-dim+1);
  475.   if (dim==1)
  476.   { bb_item p,father;
  477.     p = sdel(x);
  478.     if (p)
  479.     { 
  480.       deleted=key(p);
  481.       delete (p);
  482.       if (!st.empty())
  483.         delete (st.pop());
  484.       while (!st.empty())
  485.       { p = st.pop();
  486.         father = st.empty() ? 0 : st.top() ;
  487.         p->gr--;              
  488.         float i=p->bal();
  489.         DDUMP("rebal cur=" << (int)(key(p)) << " groesse= " << p->groesse() << " bal= " << i << " in dimension " << dim << "\n");
  490.  
  491.     tuplep help = key(p);
  492.     int help_dimp = help->cmp_dim();
  493.     help->set_cmp(help->dimension());
  494.         if (i<alpha)
  495.           if (p->sohn[right]->bal() <= d) bb_tree::lrot(p,father);
  496.           else bb_tree::ldrot(p,father);
  497.         else if (i>1-alpha)
  498.                if(p->sohn[left]->bal() > d) bb_tree::rrot(p,father);
  499.                else bb_tree::rdrot(p,father);
  500.         help->set_cmp(help_dimp);
  501.       }
  502.     }
  503.     x->set_cmp(help_dim);
  504.     return deleted; 
  505.   }
  506.  
  507.   else
  508.   { if (empty()) return 0;
  509.     if (size()==1)                     // only one tuple
  510.     { DDUMP("delete only element\n");
  511.       tuplep y=key(root);
  512.       if ( tuple_cmp(x,y) == 0 )
  513.       { delete(inf(root));
  514.     bb_tree::clear();
  515.         return y;                
  516.       }
  517.     }
  518.  
  519.     bb_item it,it1;
  520.  
  521.     x->set_cmp(x->dimension()-dim+1);
  522.  
  523.     it1 = sdel(x);
  524.     if (!it1) return 0;                  // tuple not in tree
  525.     deleted = key(it1);
  526.  
  527.  
  528.     bb_item it2 = pred(it1);
  529.                                          // delete nodelist of it1 or pred(it1)
  530.     it = st.pop();
  531.  
  532.     if (tuple_cmp(x,key(bb_tree::max()))>=0)
  533.     { DDUMP("old maximum deleted\n");    // old maximum deleted
  534.       delete(inf(it1));
  535.       inf(it)->del_tuple(x);
  536.       it2->inf = it->inf;
  537.     }
  538.     else
  539.       delete(inf(it));
  540.  
  541.     DDUMP((int)(key(it1)) << " geloescht\n" );
  542.  
  543.     delete it;
  544.     delete it1; 
  545.                      // rebalance tree
  546.                      // and delete tuple out of nodelists
  547.     while (!st.empty())
  548.     { 
  549.       it=st.pop();
  550.       inf(it)->del_tuple(x); 
  551.  
  552.       it1 = st.empty() ? 0 : st.top() ;
  553.       it->gr--;              
  554.  
  555.       float i=it->bal();
  556.       DDUMP("rebal cur=" << (int)(key(it)) << " groesse= " << it->groesse() << " bal= " << i << " in dimension " << dim << "\n");
  557.       if (i<alpha)
  558.         if (it->sohn[right]->bal() <= d) lrot(it,it1);
  559.         else ldrot(it,it1);
  560.       else if (i>1-alpha)
  561.              if(it->sohn[left]->bal() > d) rrot(it,it1);
  562.              else rdrot(it,it1);
  563.     }
  564.  
  565.     x->set_cmp(help_dim);
  566.     return deleted;
  567.   }
  568. }
  569.  
  570. //-------------------------------------------------------------------
  571. // query
  572. // returns all tuples x in the range_tree with
  573. //     lower.project(i) <= x.project(i) <= upper.project(i)
  574. //     for x.cmp_dim() <= i <= dim
  575. // by:
  576. // - perform for all tuples x with 
  577. //   lower.project(1) <= x.project(1) <= upper.project(1)
  578. //   a query in a (d-1) dimensional Range-tree 
  579.  
  580. void range_tree::query_tuples(tuplep lower, tuplep upper, dlist& L)
  581.   DPRINT("query in dimension " << dim << " on " << (int)(key(root)) << "\n");
  582.  
  583.   L.clear();
  584.  
  585.   if (size()==0) return;
  586.  
  587.   int help_diml = lower->cmp_dim();
  588.   int help_dimu = upper->cmp_dim();
  589.  
  590.   lower->set_cmp(lower->dimension()-dim+1);
  591.   upper->set_cmp(upper->dimension()-dim+1);
  592.  
  593.   bb_tree_item it;
  594.   tuplep y,y1;
  595.   
  596.   L.clear();
  597.  
  598.   if (size()==0) return;
  599.  
  600.   if (dim==1)                        // one - dimensional tree
  601.   { it=locate(lower);
  602.     while( it && (tuple_cmp(upper,key(it)) >=  0) )
  603.     { DDUMP((int)(key(it)) << "betrachtet\n");
  604.       L.append(key(it));
  605.       it = succ(it);
  606.     }
  607.     lower->set_cmp(help_diml);
  608.     upper->set_cmp(help_dimu);
  609.     return;
  610.   }
  611.  
  612.                                      // >= 2 dimensional tree
  613.   it=root;
  614.   if (size()==1)                     // no recursive calls
  615.   { 
  616.     if (check(key(it),lower,upper)) L.append(key(it));
  617.     lower->set_cmp(help_diml);
  618.     upper->set_cmp(help_dimu);
  619.     return;
  620.   }
  621.  
  622.                                      // look for nodetrees
  623.                      // necessary: access to nodes of bb_tree
  624.   bb_tree_item it1=root;   
  625.   while ((it==it1)&&(!it->blatt()))
  626.   { y=key(it);
  627.     y1=key(it1);
  628.     DDUMP(" same path " << (int)y1 << "\n");
  629.     lower->set_cmp(lower->dimension()-dim+1);
  630.     upper->set_cmp(upper->dimension()-dim+1);
  631.     if ( tuple_cmp(lower,y)<=0 ) it=it->sohn[left];
  632.       else it=it->sohn[right];
  633.     if ( tuple_cmp(upper,y1)<=0 ) it1=it1->sohn[left];
  634.       else it1=it1->sohn[right];
  635.   }
  636.                      // now paths to lower and upper part
  637.                                      // or it is a leaf
  638.   y=key(it);
  639.   if (it->blatt())
  640.   { 
  641.     if (check(y,lower,upper)) L.append(y);
  642.  
  643.     if(it!=it1)                      // it leaf, it != it1 => search on upper path
  644.     { list(range_tree_item) L1;
  645.       while (!it1->blatt())
  646.       { lower->set_cmp(lower->dimension()-dim+1);
  647.         upper->set_cmp(upper->dimension()-dim+1);
  648.         y1=key(it1);
  649.     DDUMP(" upper path " << (int)y1 << "\n");
  650.     if ( tuple_cmp(upper,y1)<=0 ) it1=it1->sohn[left];
  651.     else
  652.     { bb_item it2=it1->sohn[left];
  653.       if (!it2->blatt())
  654.         info(it2)->query_tuples(lower,upper,L1);
  655.           else 
  656.         if (check(key(it2),lower,upper)) L1.append(key(it2)); 
  657.       L.conc(L1);
  658.       it1=it1->sohn[right];
  659.         }
  660.       }
  661.       if (check(key(it1),lower,upper)) L.append(key(it1)); 
  662.     }
  663.     lower->set_cmp(help_diml);
  664.     upper->set_cmp(help_dimu);
  665.     return;
  666.   }
  667.  
  668.                                      // it no leaf => paths parted 
  669.   list(range_tree_item) L1;
  670.   while (!it->blatt())
  671.   { y=key(it);
  672.     DDUMP(" lower path " << (int)y << "\n");
  673.     lower->set_cmp(lower->dimension()-dim+1);
  674.     upper->set_cmp(upper->dimension()-dim+1);
  675.     if ( tuple_cmp(lower,y)>0 ) it=it->sohn[right];
  676.     else
  677.     { bb_item it2=it->sohn[right];
  678.       if (!it2->blatt())
  679.         info(it2)->query_tuples(lower,upper,L1);
  680.       else 
  681.     if (check(key(it2),lower,upper)) L1.append(key(it2)); 
  682.       L.conc(L1);
  683.       it=it->sohn[left];
  684.     }
  685.   } 
  686.   if (check(key(it),lower,upper)) L.append(key(it));
  687.  
  688.   while (!it1->blatt())
  689.   { y1=key(it1);
  690.     DDUMP(" upper path " << (int)y1 << "\n");
  691.     lower->set_cmp(lower->dimension()-dim+1);
  692.     upper->set_cmp(upper->dimension()-dim+1);
  693.     if ( tuple_cmp(upper,y1)<=0 ) it1=it1->sohn[left];
  694.     else
  695.     { bb_item it2=it1->sohn[left];
  696.       if (!it2->blatt())
  697.         info(it2)->query_tuples(lower,upper,L1);
  698.       else 
  699.     if (check(key(it2),lower,upper)) L1.append(key(it2)); 
  700.       L.conc(L1);
  701.       it1=it1->sohn[right];
  702.     }
  703.   }
  704.   if (check(key(it1),lower,upper)) L.append(key(it1)); 
  705.  
  706.   lower->set_cmp(help_diml);
  707.   upper->set_cmp(help_dimu);
  708.   return;
  709. }
  710.  
  711. //-------------------------------------------------------------------
  712. // all_tuples
  713. // returns all range_tree_items x in the range_tree 
  714.  
  715. list(range_tree_item) range_tree::all_tuples()
  716.  
  717.   DPRINT("all_tuples of " << int(this) << " in dimension " << dim << "\n");
  718.   
  719.   bb_item it;
  720.   list(range_tree_item) L;
  721.  
  722.   init_iterator();
  723.   while (it=rm_tree::move_iterator())
  724.     L.append(key(it));
  725.  
  726.   return L;
  727.  
  728. }
  729.  
  730.  
  731. //--------------------------------------------------------------------
  732. // Minima & Maxima
  733.  
  734. range_tree_item range_tree::min(int i)
  735. { if (i>dim || i<1)
  736.     return 0;
  737.   else 
  738.   { range_p r=this; 
  739.     while (--i) r=(range_p)r->root->inf;
  740.     return key(((bb_tree*)r)->min()); 
  741.   }
  742. }
  743.  
  744. range_tree_item range_tree::max(int i)
  745. { if (i>dim || i<1)
  746.     return 0;
  747.   else 
  748.   { range_p r=this; 
  749.     while (--i) r=(range_p)r->root->inf;
  750.     return key(((bb_tree*)r)->max()); 
  751.   }
  752. }
  753.  
  754. //--------------------------------------------------------------------
  755. //  Clear & Destruktor
  756. //  
  757.  
  758.  
  759. void range_tree::clear_tuple(tuplep& y) 
  760.    DPRINT("clear von " << (int)y << "\n");
  761.    clear_key((ent&)y);
  762.    clear_inf((ent&)y);
  763. }
  764.  
  765. void range_tree::del_tree(bb_item p)
  766.   if (!p->blatt())
  767.   {  
  768.      delete inf(p);
  769.      del_tree(p->sohn[left]);
  770.      del_tree(p->sohn[right]); 
  771.   }
  772.   else
  773.     if (p==bb_tree::max())
  774.       delete inf(p);
  775.  
  776.   delete(p);
  777.  
  778. }
  779.  
  780. void range_tree::clear()
  781. { range_tree_item it;
  782.   list(range_tree_item) L=all_tuples();
  783.   forall(it,L) 
  784.   { 
  785.      clear_tuple(it);
  786.      delete it;       
  787.   }
  788.  
  789.   if (dim==1)
  790.     bb_tree::clear();
  791.   else
  792.     if (root)
  793.       del_tree(root);
  794.  
  795.   root=0;
  796.   anzahl=0;
  797.   first=0;
  798. }
  799.  
  800.  
  801. range_tree::~range_tree()
  802.  
  803.    DPRINT("Destruktor in Dimension " << dim << "\n");
  804.  
  805.    if (root)
  806.    { del_tree(root);
  807.      root = 0;
  808.    }
  809.  
  810. }
  811.  
  812.   
  813. //--------------------------------------------------------------------
  814.