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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _range_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. #include <LEDA/impl/range_tree.h>
  12. // Let's start with some simple member functions of class rt_elem
  13. // the 2-dimensional constructor
  14. //
  15. rt_elem::rt_elem(GenPtr k0, GenPtr k1, GenPtr i) {
  16.   rt_keys=new GenPtr[2];
  17.   rt_keys[0]=k0; rt_keys[1]=k1;
  18.   rt_inf=i;
  19. }
  20. // the 3-dimensional constructor
  21. //
  22. rt_elem::rt_elem(GenPtr k0, GenPtr k1, GenPtr k2, GenPtr i) {
  23.   rt_keys=new GenPtr[3];
  24.   rt_keys[0]=k0; rt_keys[1]=k1; rt_keys[2]=k2;
  25.   rt_inf=i;
  26. }
  27. // the d-dimensional constructor
  28. //
  29. rt_elem::rt_elem(int dim, GenPtr* k, GenPtr i) {
  30.   rt_keys=new GenPtr[dim];
  31.   for( int d=0; d<dim; d++ )
  32.     rt_keys[d]=k[d];
  33.   rt_inf=i;
  34. }
  35. // And here are the member functions of class range_tree
  36. // insert new_elem into the primary tree and update its secondary 
  37. // structures if lev<dim-1
  38. //
  39. void range_tree::rt_insert( rt_item new_elem )
  40. {
  41. #ifdef DEBUG
  42.   newline;
  43.   for( int auxl=0; auxl<lev; auxl++ ) cout << "t";
  44.   cout << "insert " << (int) new_elem->inf() << ":   "; cout.flush();
  45. #endif
  46.   if( lev<dim-1 ) { // take care of secondary structures
  47.     base_tree_item p, new_leaf;
  48.     range_tree* sec;
  49.     // insert the new element into the primary tree 
  50.     //
  51.     aux.clear();
  52.     new_leaf = base_tree::insert( new_elem, new_range_tree(dim,lev+1), 
  53.                new_range_tree(dim,lev+1) );
  54.   
  55.     // now we insert the new element into all secondary structures of 
  56.     // nodes on the path from the root to the new leaf with a non-empty
  57.     // secondary structure (remember that these nodes are not in aux)
  58.     //
  59.     p = root();
  60.     while( p ) {
  61.       sec = (range_tree*) inf(p);
  62.       if( sec->size() )
  63.         sec->rt_insert(new_elem);
  64.       if( cmp(new_elem,key(p))<=0 )
  65.         p = l_child(p);
  66.       else
  67.         p = r_child(p);
  68.     }
  69.     // and into the (empty) secondary structure of the new leaf
  70.     //
  71.     ((range_tree*) inf(new_leaf))->rt_insert(new_elem);
  72.     // for all nodes appended to aux by the function propagate_change(), 
  73.     // we rebuild the secondary structure from scratch
  74.     //
  75.     rt_item* elem_array = new rt_item[size()]; // array of elements
  76.     int elem_no; // number of elements
  77.     forall( p, aux ) {
  78.       elem_no = elements_in_subtree(elem_array, p);
  79.       ((range_tree*) inf(p))->build_tree(elem_array, 0, elem_no-1);
  80.     }
  81.   
  82.     delete elem_array;
  83.   }
  84.   else
  85.     // for lev==dim-1 the range tree is just an ordinary search tree
  86.     //
  87.     base_tree::insert( new_elem, 0, 0 );
  88. }
  89. // recursively build a range tree for the elements 
  90. // elem_array[lidx],...,elem_array[ridx]
  91. // if p==0 we build the tree on this level and the secondary structure of the
  92. // root, otherwise we just build the secondary structure of p
  93. //
  94. void range_tree::build_tree( rt_item* elem_array, int lidx, int ridx, 
  95.      base_tree_item p )
  96. {
  97. #ifdef DEBUG
  98.   newline;
  99.   for( int gg=0; gg<lev; gg++ )
  100.     cout << "t";
  101.   cout << "build_tree " << p << ":   ";
  102.   cout.flush();
  103. #endif
  104.   int i;
  105.   // the last level of the range tree is just a binary search tree
  106.   //
  107.   if( lev==dim-1 ) {
  108.     for( i=lidx; i<=ridx; i++ ) {
  109. #ifdef DEBUG
  110.       newline;
  111.       for( int gg=0; gg<lev; gg++ )
  112.         cout << "t";
  113.       cout << "insert " << (int) elem_array[i]->inf() << ":   ";
  114.       cout.flush();
  115. #endif
  116.       base_tree::insert( elem_array[i], 0, 0 );
  117.     }
  118.     return;
  119.   }
  120.   // we are entering this level for the first time, therefor we have
  121.   // to insert all elements and sort them according to the new level
  122.   //
  123.   if( !p ) {
  124.     for( i=lidx; i<=ridx; i++ ) {
  125. #ifdef DEBUG
  126.       newline;
  127.       for( int gg=0; gg<lev; gg++ )
  128.         cout << "t";
  129.       cout << "insert " << (int) elem_array[i]->inf() << ":   ";
  130.       cout.flush();
  131. #endif
  132.       base_tree::insert( elem_array[i], new_range_tree(dim,lev+1), 
  133.                                         new_range_tree(dim,lev+1) );
  134.     }
  135.     p = root();
  136.     elem_array = new rt_item[ridx-lidx+1];
  137.     lidx = 0;
  138.     ridx = elements_in_subtree(elem_array,p)-1; /* get sorted array */
  139.   }
  140.   // build the secondary structure
  141.   //
  142.   ((range_tree*) inf(p))->build_tree(elem_array, lidx, ridx);
  143.   // if p is an inner node, we recursively build the secondary structures
  144.   // of its children
  145.   //
  146.   if (is_inner(p)) {
  147.     int l=lidx, r=ridx, med=(l+r)/2, c=cmp(elem_array[med],key(p));
  148.     // "split" the array at key(p)
  149.     //
  150.     while( c ) {
  151.       if( c>0 )
  152. r = med-1;
  153.       else
  154. l = med+1;
  155.       med = (l+r)/2;
  156.       c = cmp(elem_array[med], key(p));
  157.     }
  158.     if (r_child(p))
  159.       build_tree(elem_array, med + 1, ridx, r_child(p));
  160.     if (l_child(p))
  161.       build_tree(elem_array, lidx, med, l_child(p));
  162.   }
  163.   // free the memory of the array elem_array, if we are done
  164.   //
  165.   if( p==root() )
  166.     delete elem_array;
  167. }
  168. // compute a sorted array (according to the actual level) of all 
  169. // elements in the subtree rooted at subroot and return their number
  170. //
  171. int range_tree::elements_in_subtree( rt_item* elem_array, 
  172.      base_tree_item subroot )
  173. {
  174.   int elem_no=0;
  175.   base_tree_item p=subroot, q=subroot;
  176.   while( is_inner(p) ) // find leftmost leaf
  177.     p = l_child(p);
  178.   while( is_inner(q) ) // find rightmost leaf
  179.     q = r_child(q);
  180.   while( p!=q ) { // collect all elements inbetween
  181.     elem_array[elem_no++] = rt_item(key(p));
  182.     p = succ(p);
  183.   }
  184.   elem_array[elem_no++] = rt_item(key(q));
  185.   return elem_no; // return the number of elements
  186. }
  187. // return a list of all elements in the tree whose key is between
  188. // left and right on each level
  189. //
  190. void range_tree::rt_query( rt_item& Left, rt_item& Right, 
  191.    list<rt_item>& res )
  192. {
  193.   if( size()>0 ) { // avoid special case
  194.     base_tree_item p, q;
  195.     if( lev<dim-1 ) { // we have to perform recursive quieries
  196.       // find the last node common to both search paths
  197.       //
  198.       p = root();
  199.       while( is_inner(p) ) {
  200. if( cmp(Right,key(p))<=0 )
  201.   p = l_child(p);
  202. else if( cmp(Left,key(p))>0 )
  203.   p = r_child(p);
  204. else
  205.   break;
  206.       }
  207.       if( is_inner(p) ) {
  208.         // traverse the left subpath
  209. //
  210. q = l_child(p);
  211. while( is_inner(q) ) {
  212.   if( cmp(Left,key(q))<=0 ) {
  213.     if( r_child(q) )
  214.       // recursively query all nodes right to the subpath
  215.       //
  216.       ((range_tree*) inf(r_child(q)))->rt_query(Left,Right,res);
  217.     q = l_child(q);
  218.   }
  219.   else
  220.     q = r_child(q);
  221. }
  222. if( cmp(Left,key(q))<=0 && cmp(Right,key(q))>=0 )
  223.   ((range_tree*) inf(q))->rt_query(Left,Right,res);
  224.         // traverse the right subpath
  225. //
  226. q = r_child(p);
  227. while( is_inner(q) ) {
  228.   if( cmp(Right,key(q))>0 ) {
  229.     if( l_child(q) )
  230.       // recursively query all nodes left to the subpath
  231.       //
  232.       ((range_tree*) inf(l_child(q)))->rt_query(Left,Right,res);
  233.     q = r_child(q);
  234.   }
  235.   else
  236.     q = l_child(q);
  237. }
  238. if( cmp(Left,key(q))<=0 && cmp(Right,key(q))>=0 )
  239.   ((range_tree*) inf(q))->rt_query(Left,Right,res);
  240.       }
  241.       else {
  242.         // we only have to look at one leaf
  243. //
  244. if( cmp(Left,key(p))<=0 && cmp(Right,key(p))>=0 )
  245.   ((range_tree*) inf(p))->rt_query(Left,Right,res);
  246.       }
  247.     }
  248.     else {
  249.       // append all elements between left and right on level dim-1
  250.       // to the res
  251.       //
  252.       p = locate_succ(Left);
  253.       while( p && cmp(key(p),Right)<=0 ) {
  254.         res.append( rt_item(key(p)) );
  255.         p = succ(p);
  256.       }
  257.     }
  258.   }
  259. }
  260. // delete elem in the primary tree and update its secondary 
  261. // structures if lev<dim-1
  262. //
  263. void range_tree::rt_del( rt_item elem )
  264. {
  265.   if( lev<dim-1 ) { // take care of secondary structures
  266.     base_tree_item p;
  267.     // delete elem in all secondary structures on the search path to elem
  268.     //
  269.     p = root();
  270.     while( is_inner(p) ) {
  271.       ((range_tree*) inf(p))->rt_del(elem);
  272.       if( cmp(elem,key(p))<=0 )
  273.         p = l_child(p);
  274.       else
  275.         p = r_child(p);
  276.     };
  277.     // and in the primary tree
  278.     //
  279.     aux.clear();
  280.     base_tree::del_item(p);
  281.     // for all nodes appended to aux by the function propagate_change(), 
  282.     // we rebuild the secondary structure from scratch
  283.     //
  284.     rt_item* elem_array = new rt_item[size()]; // array of elements
  285.     int elem_no; // number of elements
  286.     forall( p, aux ) {
  287.       elem_no = elements_in_subtree(elem_array, p);
  288.       ((range_tree*) inf(p))->build_tree(elem_array, 0, elem_no-1);
  289.     }
  290.   
  291.     delete elem_array;
  292.   }
  293.   else
  294.     // for lev==dim-1 the range tree is just an ordinary search tree
  295.     //
  296.     base_tree::del(elem);
  297. }
  298. // return a list of all elements in the tree
  299. //
  300. list<rt_item> range_tree::all_items()
  301. {
  302.   list<rt_item> res;
  303.   if( !empty() ) {
  304.     base_tree_item p=base_tree::min(),
  305.                    q=base_tree::max();
  306.     res.append( (rt_item) key(p) );
  307.     while( p!=q ) {
  308.       p = cyclic_succ(p);
  309.       res.append( (rt_item) key(p) );
  310.     }
  311.   }
  312.   return res;
  313. }
  314. // compute minimum element on a given level
  315. //
  316. rt_item range_tree::rt_min( int d ) 
  317. {
  318.   if( empty() ) return 0;
  319.   if( lev<d ) // proceed to next level
  320.     return ((range_tree*) inf(root()))->rt_min(d);
  321.   else 
  322.     return( (rt_item) key(base_tree::min()) );
  323. }
  324. // compute maximum element on a given level
  325. //
  326. rt_item range_tree::rt_max( int d ) {
  327.   if( empty() ) return 0;
  328.   if( lev<d ) // proceed to next level
  329.     return ((range_tree*) inf(root()))->rt_max(d);
  330.   else 
  331.     return( (rt_item) key(base_tree::max()) );
  332. }