⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _range_tree.c

📁 数据类型和算法库LEDA 数据类型和算法库LEDA
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
+
+  LEDA  3.0
+
+
+  _range_tree.c
+
+
+  Copyright (c) 1992  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 6600 Saarbruecken, FRG     
+  All rights reserved.
+ 
*******************************************************************************/



// ------------------------------------------------------------------
//
// d-dimensional Range Trees
//
// Michael Wenzel     (1990)
//
// Implementation follows
// Data Structure Lecture, K. Mehlhorn, Summer 1989
// K. Mehlhorn: Data Structures and Algorithms, Vol. 3
//
// ------------------------------------------------------------------

#include <LEDA/impl/range_tree.h>

enum left_or_right {left = 0, right = 1};

#undef TEST
#undef DUMP
#undef STAT

#ifdef TEST
#define DPRINT(x) cout << x
#else
#define DPRINT(x)
#endif

#ifdef DUMP
#define DDUMP(x) cout << x
#else
#define DDUMP(x)
#endif

#ifdef STAT
#define DSTAT print_statistics() 
#else
#define DSTAT
#endif

//------------------------------------------------------------------
// member-functions of class tuple
//
// Michael Wenzel          (1990)
//------------------------------------------------------------------

  tuple::tuple()
      { 
	d=0;
	t=0; }

  tuple::tuple(GenPtr a, GenPtr b)
      { 
	d=2;
	t=new GenPtr[2]; 
        t[0] = a;
        t[1] = b; }

  tuple::tuple(GenPtr a, GenPtr b, GenPtr c)
      { 
	d=3;
	t=new GenPtr[3]; 
        t[0] = a;
        t[1] = b;  
        t[2] = c;  }

  tuple::tuple(int dim)
      { 
	d=dim;
        inf = 0;
	t=new GenPtr[dim]; }

  tuple::~tuple()
      { if (t)
          delete t;
      }

//-------------------------------------------------------------------
//  RANGE TREE
//-------------------------------------------------------------------


int range_tree::tuple_cmp(tuplep p, tuplep q) const
{  int i = p->cmp_dim();
   int stop = (i==0) ? p->d-1 : i-1;
   int res;
   while ((res=cmp_tuple_entry(i,p,q))==0 && i!=stop) 
     i=(i+1)%p->d;
   return res;
}
    
// ------------------------------------------------------------
// lrot() , rrot() , ldrot() , rdrot()
// Rotationen am Knoten p

void range_tree::lrot(bb_item p, bb_item q)
{
  bb_item h = p->sohn[right];
  int help_dim = key(h)->cmp_dim();
  key(h)->set_cmp(key(h)->dimension()-dim+1);

  DDUMP("lrot "<< (int)key(p)) ; 
    if (q) DDUMP(" Vater " << (int)(key(q)));
  DDUMP("\n");

  p->sohn[right] = h->sohn[left];
  h->sohn[left] = p;
  if (!q)
    root=h;
  else
  { if (tuple_cmp(key(h),key(q))>0)
      q->sohn[right]=h;
    else
      q->sohn[left]=h;
  }
  p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  h->gr=p->groesse()+h->sohn[right]->groesse();

						// update nodelists
  list<range_tree_item> L;
  range_tree_item x;

  bb_item s = p->sohn[left];
  if (s->blatt())
    inf(h)->insert_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(h)->insert_tuple(x);
    L.clear();
  }

  s = h->sohn[right];
  if (s->blatt())
    inf(h)->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(p)->del_tuple(x);
  }

  key(h)->set_cmp(help_dim);
}

void range_tree::rrot(bb_item p, bb_item q)
{
  bb_item h = p->sohn[left];
  int help_dim = key(h)->cmp_dim();
  key(h)->set_cmp(key(h)->dimension()-dim+1);

  DDUMP("rrot "<< (int)(key(p))) ; 
    if (q) DDUMP(" Vater " << (int)(key(q)));
  DDUMP("\n");

  p->sohn[left] = h->sohn[right];
  h->sohn[right] = p;
  if (!q) root=h;
  else
  { if (tuple_cmp(key(h),key(q))>0)
      q->sohn[right] = h;
    else
      q->sohn[left] = h; }
  p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  h->gr=p->groesse()+h->sohn[left]->groesse();

						// update nodelists
  list<range_tree_item> L;
  range_tree_item x;
  bb_item s = p->sohn[right];
  if (s->blatt())
    inf(h)->insert_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(h)->insert_tuple(x);
    L.clear();
  }

  s = h->sohn[left];
  if (s->blatt())
    inf(p)->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(p)->del_tuple(x);
  }
  key(h)->set_cmp(help_dim);
}

void range_tree::ldrot(bb_item p, bb_item q)
{
  bb_item h = p->sohn[right];
  bb_item g = h->sohn[left];
  int help_dim = key(h)->cmp_dim();
  key(h)->set_cmp(key(h)->dimension()-dim+1);

  DDUMP("ldrot "<< (int)(key(p))) ; 
    if (q) DDUMP(" Vater " << (int)(key(q)));
  DDUMP("\n");

  p->sohn[right] = g->sohn[left];
  h->sohn[left] =  g->sohn[right];
  g->sohn[left] = p;
  g->sohn[right] = h;
  if (!q) root=g;
  else
  { if (tuple_cmp(key(h),key(q))>0)
      q->sohn[right] =g ;
    else 
      q->sohn[left] = g ; }
  p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  h->gr=h->sohn[left]->groesse()+h->sohn[right]->groesse();
  g->gr=p->groesse()+h->groesse();
						// update nodelists
  list<range_tree_item> L;
  range_tree_item x;
  range_tree* help = (range_tree*)g->inf;

  g->inf = p->inf;

  bb_item s = p->sohn[right];
  if (s->blatt())
    inf(h)->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(h)->del_tuple(x);
    L.clear();
  }

  s = h->sohn[left];
  if (s->blatt())
    help->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) help->del_tuple(x);
    L.clear();
  }

  s = p->sohn[left];
  if (s->blatt())
    help->insert_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) help->insert_tuple(x);
  }

  p->inf = (GenPtr) help;
  key(h)->set_cmp(help_dim);
}

void range_tree::rdrot(bb_item p, bb_item q)

{
  bb_item h = p->sohn[left];
  bb_item g = h->sohn[right];
  int help_dim = key(h)->cmp_dim();
  key(h)->set_cmp(key(h)->dimension()-dim+1);

  DDUMP("rdrot "<< (int)(key(p))) ; 
    if (q) DDUMP(" Vater " << (int)(key(q)));
  DDUMP("\n");

  p->sohn[left] = g->sohn[right];
  h->sohn[right] =  g->sohn[left];
  g->sohn[right] = p;
  g->sohn[left] = h;
  if (!q) root=g;
  else
  { if (tuple_cmp(key(h),key(q))>0)
      q->sohn[right] =g ;
    else 
      q->sohn[left] = g ; }
  p->gr=p->sohn[left]->groesse()+p->sohn[right]->groesse();
  h->gr=h->sohn[left]->groesse()+h->sohn[right]->groesse();
  g->gr=p->groesse()+h->groesse();
						// update nodelists
  list<range_tree_item> L;
  range_tree_item x;
  range_tree* help = (range_tree*)g->inf;

  g->inf = p->inf;

  bb_item s = p->sohn[left];
  if (s->blatt())
    inf(h)->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) inf(h)->del_tuple(x);
    L.clear();
  }

  s = h->sohn[right];
  if (s->blatt())
    help->del_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) help->del_tuple(x);
    L.clear();
  }

  s = p->sohn[right];
  if (s->blatt())
    help->insert_tuple(key(s));
  else
  { L = inf(s)->all_tuples();
    forall(x,L) help->insert_tuple(x);
  }

  p->inf = (GenPtr) help;
  key(h)->set_cmp(help_dim);
}
 
// ------------------------------------------------------------
// check(x,y,z)                              
// check if a tuple x lies between y and z
// some coordinates are already checked

bool range_tree::check(tuplep x, tuplep y, tuplep z)

{ bool found=true;
  int help_dim = x->cmp_dim();

  for (int i=x->dimension()-dim+1;i<=x->dimension();i++)
  { x->set_cmp(i);
    if ((tuple_cmp(x,y)<0)||(tuple_cmp(x,z)>0)) 
    { x->set_cmp(help_dim);
      return false;
    }
  }
  x->set_cmp(help_dim);
  return found;
}


//-------------------------------------------------------------------
// insert_tuple
// insert a tuple into a range_tree:             
// - insert tuple according to first coordinate in main tree (bb-alpha)
// - insert tuple according to second coordinate in all nodetrees
//   on the path of the main tree from the root to the tuple

range_tree_item range_tree::insert_tuple(tuple* x)

{ bb_tree_item inserted;
  tuplep y;
  int help_dim = x->cmp_dim();
  x->set_cmp(x->dimension()-dim+1);

  DPRINT("insert tuple " << (int)x << " in "  << dim << " dimension ") ;
  DPRINT("and comparedimension " << x->cmp_dim() << "\n");

  if (inserted=rm_tree::lookup(x)) 
  { 
    tuplep y=key(inserted);
    clear_inf((GenPtr&)y);                 // clear tuple and change inf
    y->info() = x->info();
    copy_inf((GenPtr&)y);
    clear_tuple(x);
    delete x;
 
    return y;
  }

  if (dim==1) 
  { bb_tree_item t,father;
    inserted = sinsert(x,0);

    if (!st.empty())
      st.pop();                       // pop father of leaf
  
                                      // rebalancieren
    while (!st.empty())
    { t=st.pop();
      father = st.empty() ? 0 : st.top();
      t->gr++;  
      float i = t->bal();

      DDUMP("rebal cur=" << (int)(key(t)) << " groesse= " << t->groesse() << " bal= " << i << " in Dimension 1\n");

      tuplep help = key(t);
      int help_dimt = help->cmp_dim();
      help->set_cmp(help->dimension());
      if (i < alpha)
        if (t->sohn[right]->bal()<=d) bb_tree::lrot(t,father);
        else bb_tree::ldrot(t,father);
      else if (i>1-alpha) 
             if (t->sohn[left]->bal() > d ) bb_tree::rrot(t,father);
  	   else bb_tree::rdrot(t,father);
      help->set_cmp(help_dimt);
    }
    x->set_cmp(help_dim);

    return key(inserted);
  }

  else
  { bb_tree_item it,it1;                
    range_tree*  t = new_range_tree(dim-1);

    it = sinsert(x,t);
    inserted = it ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -