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

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  range_tree.h
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #ifndef LEDA_RANGE_TREE_H
  12. #define LEDA_RANGE_TREE_H
  13. #include <LEDA/basic.h>
  14. #include <LEDA/list.h>
  15. // the elements (an information together with its associated array 
  16. // of keys) are stored in the class rt_elem
  17. //
  18. class rt_elem {
  19.   GenPtr  rt_inf; // the information
  20.   GenPtr* rt_keys; // an array of keys
  21.  public:
  22.   LEDA_MEMORY(rt_elem);
  23.   // some constructors, destructor
  24.   //
  25.   rt_elem() { rt_keys=0; rt_inf=0; }
  26.   rt_elem(GenPtr k0, GenPtr k1, GenPtr i);
  27.   rt_elem(GenPtr k0, GenPtr k1, GenPtr k2, GenPtr i);
  28.   rt_elem(int dim, GenPtr* k, GenPtr i);
  29.   virtual ~rt_elem() { if( rt_keys ) delete rt_keys; }
  30.   // accessing infotmation and keys
  31.   //
  32.   GenPtr& key(int d) { return rt_keys[d]; }
  33.   GenPtr& inf() { return rt_inf; }
  34.   friend class range_tree;
  35. };
  36. // a pointer to a rt_elem is called rt_item
  37. //
  38. typedef rt_elem* rt_item;
  39. // the range tree is derived from a binary tree of type base_tree
  40. //
  41. #include <LEDA/impl/bb_tree.h>
  42. typedef bb_tree base_tree;
  43. typedef bb_tree_item base_tree_item;
  44. // Here comes the definition ...
  45. //
  46. class range_tree : public base_tree
  47. {
  48.   protected:
  49.     list<base_tree_item> aux; // auxiliary list of base_tree_items
  50.     int dim; // the dimension of the structure 
  51.     int lev; // the level of this tree 
  52.     // some internal functions
  53.     
  54.     void rt_insert( rt_item rt_key );
  55.     void rt_del( rt_item rt_key );
  56.     void rt_query( rt_item&, rt_item&, list<rt_item>& );
  57.     void build_tree( rt_item* elem_array, int l, int r, base_tree_item p=0 ) ;
  58.     int elements_in_subtree( rt_item* elem_array, base_tree_item subroot );
  59.   
  60.     // to compare two elements in the range tree, we first compare their
  61.     // keys on the appropriate level.
  62.     //
  63.     int cmp( GenPtr x, GenPtr y ) const {
  64.       register int c, d=lev;
  65.       do {
  66.         c=rt_cmp(d,rt_item(x)->rt_keys,rt_item(y)->rt_keys);
  67.       } while( !c && (d=++d%dim)!=lev );
  68.       return c;
  69.     }
  70.   
  71.     // this function is called for every structural change in the base_tree;
  72.     // the first argument specifies the operation which forced this change.
  73.     // (cf. the class bin_tree)
  74.     //
  75.     // if we're not on the highest level and a child of a node changes, 
  76.     // we have to recompute its secondary structure. Hence we append the
  77.     // parent node to an auxiliary list (which will be processed in "insert").
  78.     // to avoid duplicate entries in the list, we clear the secondary structure
  79.     // of an node as soon as it is appended. Then a node is in the list iff
  80.     // its secondary structure is empty.
  81.     //
  82.     void propagate_modification( int where, GenPtr parent, GenPtr /* child */) 
  83.     { 
  84.       range_tree* sec = (range_tree*) inf((base_tree_item) parent);
  85.   
  86.       // sec==0 iff we are on the highest level (lev==dim-1)
  87.       //
  88.       if ( sec ) // select the "interesting" cases
  89.        switch( where )
  90.        { case 1: // insert
  91.           aux.append((base_tree_item)parent); 
  92.   break;
  93.   
  94.          case 4:// rotation
  95.          case 5:// rotation
  96.          case 7:// double rotation 
  97.          case 8:// double rotation 
  98.          case 9:// double rotation
  99.   if ( sec->size() ) 
  100.   { // if parent is already in the list, don't append it again
  101.     sec->clear();
  102.             aux.append((base_tree_item)parent); 
  103.   }
  104.         }
  105.      }
  106.     // let's redefine the virtual functins of the base tree as we need them
  107.     //
  108.     // because both informations and keys in the base tree are pointers
  109.     // we never need to copy them
  110.     //
  111.     void copy_key( GenPtr& ) const {}
  112.     void copy_inf( GenPtr& ) const {}
  113.   
  114.     // keys are only cleared on the lowest level
  115.     //
  116.     void clear_key( GenPtr& x ) const {
  117.       if( lev==0 ) {
  118.         rt_clear_key( rt_item(x)->rt_keys );
  119.         rt_clear_inf( rt_item(x)->rt_inf );
  120.         delete rt_item(x);
  121.       }
  122.     }
  123.   
  124.     void print_key( GenPtr x ) const { rt_print_key(lev,rt_item(x)->rt_keys); }
  125.   
  126.     // informations are always a pointer to a range tree
  127.     //
  128.     void clear_inf( GenPtr& x ) const { if( x ) delete ((range_tree*) x); }
  129.     void clear_iinf( GenPtr& x ) const { if( x ) delete ((range_tree*) x); }
  130.     void print_inf( GenPtr x ) const { if( x ) ((range_tree*) x)->print(); }
  131.   
  132.     // here are the virtual functions which have to be changed by a derived
  133.     // class of class range_tree
  134.     //
  135.   
  136.     virtual int rt_cmp( int d, GenPtr* x, GenPtr* y ) const { 
  137.       return compare(x[d],y[d]); 
  138.     }
  139.   
  140.     virtual void rt_copy_key( GenPtr*& ) const {}
  141.     virtual void rt_clear_key( GenPtr*& ) const {}
  142.   
  143.     virtual void rt_print_key( int, GenPtr*& ) const {}
  144.   
  145.     virtual void rt_copy_inf( GenPtr& ) const {}
  146.     virtual void rt_clear_inf( GenPtr& ) const {}
  147.   
  148.     virtual range_tree* new_range_tree( int dimension, int level=0 ) { 
  149.       return new range_tree(dimension,level); 
  150.     }
  151.   public:
  152.     LEDA_MEMORY( range_tree );
  153.   
  154.     // constructor and virtual destructor
  155.     //
  156.     range_tree( int d, int l=0 ) { dim=d; lev=l; }
  157.     virtual ~range_tree() { clear(); }
  158.   
  159.     rt_item rt_min( int d );
  160.     rt_item rt_max( int d );
  161.   
  162.     void clear() { base_tree::clear(); aux.clear(); }
  163.   
  164.     void del( rt_item elem ) {
  165.       if( lookup(elem) )
  166.         rt_del(elem);
  167.     }
  168.   
  169.     rt_item lookup( rt_item elem ) {
  170.       base_tree_item p = base_tree::lookup(elem);
  171.       return( p ? (rt_item) key(p) : 0 );
  172.     }
  173.   
  174.     rt_item insert( rt_item elem ) {
  175.       rt_item old = lookup(elem);
  176.       if( !old ) {
  177.         rt_insert(elem);
  178.         return elem;
  179.       }
  180.       else {
  181.         rt_clear_key( elem->rt_keys );
  182.         rt_clear_inf( old->rt_inf );
  183.         old->rt_inf = elem->rt_inf;
  184.         delete elem;
  185.         return old;
  186.       }
  187.     }
  188.   
  189.     list<rt_item> query( rt_item l, rt_item r ) {
  190.       list<rt_item> res;
  191.       rt_query( l, r, res );
  192.       return res;
  193.     }
  194.     list <rt_item> L; // auxiliary list for iterations
  195.     list<rt_item> all_items();
  196.     void init_iteration() { L = all_items(); }
  197. };
  198. #endif