Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_splay_treeRk.H
1 /*
2  * Top Dowm Splay Trees
3  */
4 
5 /* This code is a c++ adaptation of Danny Sleator code. It can be loaded from
6 
7  http://www.link.cs.cmu.edu/link/ftp-site/splaying/SplayTree.java
8 
9  */
10 
11 # ifndef TPL_SPLAY_TREE_H
12 # define TPL_SPLAY_TREE_H
13 
14 # include <tpl_binNodeXt.H>
15 
16 
17 using namespace Aleph;
18 
19 
20  template <template <class> class NodeType, typename Key, class Compare>
22 {
23 public:
24 
25  typedef NodeType<Key> Node;
26 
27 private:
28 
29  Node * root;
30  Compare & cmp;
31 
32 public:
33 
35  typedef Key key_type;
36 
38  Compare & key_comp() { return cmp; }
39 
41  Compare & get_compare() { return key_comp(); }
42 
45  void splay(const Key & key)
46  {
47  Node header(sentinelCtor);
48  Node * head_ptr = &header;
49  Node * l = head_ptr;
50  Node * r = head_ptr;
51  Node * t = root;
52 
53  while (true)
54  if (cmp(key, KEY(t)))
55  {
56  if (LLINK(t) == Node::NullPtr)
57  break;
58 
59  if (cmp(key, KEY(LLINK(t))))
60  {
61  t = rotate_to_right_xt(t);
62  if (LLINK(t) == Node::NullPtr)
63  break;
64  }
65 
66  LLINK(r) = t;
67  r = t;
68  t = LLINK(t);
69  }
70  else if (cmp(KEY(t), key))
71  {
72  if (RLINK(t) == Node::NullPtr)
73  break;
74 
75  if (cmp(KEY(RLINK(t)), key))
76  {
77  t = rotate_to_left_xt(t);
78  if (RLINK(t) == Node::NullPtr)
79  break;
80  }
81 
82  RLINK(l) = t;
83  l = t;
84  t = RLINK(t);
85  }
86  else
87  break;
88 
89  /*
90  t points to the splayed node
91  l points to the predecessor of splayed node
92  r points to the predecessor of splayed node
93  */
94 
95  if (l != head_ptr)
96  COUNT(l) += -COUNT(RLINK(l)) + COUNT(LLINK(t));
97  if (r != head_ptr)
98  COUNT(r) += -COUNT(LLINK(r)) + COUNT(RLINK(t));
99 
100  /* reassembling of sub trees in one with t as root */
101  RLINK(l) = LLINK(t);
102  LLINK(r) = RLINK(t);
103 
104  LLINK(t) = RLINK(head_ptr);
105  RLINK(t) = LLINK(head_ptr);
106 
107  COUNT(t) = COUNT(LLINK(t)) + 1 + COUNT(RLINK(t));
108 
109  root = t;
110  }
111 
113  GenTdSplayTreeRk(Compare & __cmp)
114  : root(Node::NullPtr), cmp(__cmp)
115  {
116  // Empty
117  }
118 
119  GenTdSplayTreeRk(Compare && __cmp)
120  : root(Node::NullPtr), cmp(__cmp)
121  {
122  // Empty
123  }
124 
125  void swap(GenTdSplayTreeRk & tree)
126  {
127  std::swap(root, tree.root);
128  std::swap(cmp, tree.cmp);
129  }
130 
132  virtual ~GenTdSplayTreeRk() { /* empty */ }
133 
134 private:
135 
136  Node * __insert(Node * p)
137  {
138  COUNT(p) = COUNT(root) + 1;
139  if (cmp(KEY(p), KEY(root)))
140  {
141  COUNT(root) -= COUNT(LLINK(root));
142  LLINK(p) = LLINK(root);
143  RLINK(p) = root;
144  LLINK(root) = Node::NullPtr;
145  }
146  else
147  {
148  COUNT(root) -= COUNT(RLINK(root));
149  RLINK(p) = RLINK(root);
150  LLINK(p) = root;
151  RLINK(root) = Node::NullPtr;
152  }
153 
154  return root = p; // inserted node become root
155  }
156 
157 public:
158 
165  Node * insert(Node * p)
166  {
167  I(p != Node::NullPtr);
168  I(COUNT(p) == 1);
169  I(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
170 
171  /* test insertion in empty tree */
172  if (root == Node::NullPtr)
173  return root = p;
174 
175  const Key & key = KEY(p);
176 
177  splay(key);
178 
179  if (are_equals<Key, Compare>(KEY(root), key, cmp))
180  return NULL; // item is already in tree
181 
182  return __insert(p);
183  }
184 
185  Node * insert_dup(Node * p)
186  {
187  I(p != Node::NullPtr);
188  I(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
189 
190  /* test insertion in empty tree */
191  if (root == Node::NullPtr)
192  return root = p;
193 
194  splay(KEY(p));
195 
196  return __insert(p);
197  }
198 
206  Node * search(const Key & key)
207  {
208  if (root == Node::NullPtr)
209  return NULL;
210 
211  splay(key);
212 
213  return are_equals<Key, Compare>(KEY(root), key) ? root : NULL;
214  }
215 
216  Node * search_or_insert(Node * p)
217  {
218  if (root == Node::NullPtr)
219  return root = p;
220 
221  const Key & key = KEY(p);
222  splay(key);
223  if (are_equals<Key, Compare>(key, KEY(root), cmp))
224  return root;
225 
226  return __insert(p);
227  }
228 
238  Node * remove(const Key & key)
239  {
240  if (root == Node::NullPtr)
241  return NULL;
242 
243  splay(key);
244 
245  if (no_equals<Key, Compare>(KEY(root), key, cmp))
246  return NULL; /* key not found */
247 
248  Node * ret_val = root; /* store node to delete */
249 
250  if (LLINK(root) == Node::NullPtr)
251  root = RLINK(root);
252  else
253  {
254  Node * p = RLINK(root);
255  root = LLINK(root);
256  splay(key);
257  RLINK(root) = p;
258  }
259 
260  ret_val->reset();
261 
262  return ret_val;
263  }
264 
266  Node *& getRoot()
267  {
268  return root;
269  }
270 
271  bool verify() const { return check_rank_tree(root); }
272 
274  size_t size() const
275  {
276  return COUNT(root);
277  }
278 
280  bool is_empty() const
281  {
282  return root == Node::NullPtr;
283  }
284 
297  std::pair<int, Node*> position (const Key & key)
298  {
299  std::pair<int, Node*> ret_val;
300 
301  splay(key);
302 
303  if (are_equals<Key, Compare>(key, KEY(root), cmp))
304  {
305  ret_val.first = COUNT(LLINK(root));
306  ret_val.second = root;
307  }
308  else
309  ret_val.first = -1;
310 
311  return ret_val;
312  }
313 
344  std::pair<int, Node*> find_position (const Key & key)
345  {
346  std::pair<int, Node*> r(-2, NULL);
347 
348  r.first = COUNT(Splay(key));
349  r.second = root;
350 
351  return r;
352  }
353 
364  Node * select (const size_t & i)
365  {
366  return Aleph::select(root, i);
367  }
368 };
369 
370 
371  template <typename Key, class Compare = Aleph::less<Key>>
372 class Splay_Tree_Rk : public GenTdSplayTreeRk<BinNodeXt, Key, Compare>
373 {
374 public:
375 
376  Splay_Tree_Rk(Compare && cmp = Compare())
378  {
379  // empty
380  }
381 
382  Splay_Tree_Rk(Compare & cmp)
384  {
385  // empty
386  }
387 };
388 
389 
390  template <typename Key, class Compare = Aleph::less<Key>>
391 class Splay_Tree_Rk_Vtl : public GenTdSplayTreeRk<BinNodeXtVtl, Key, Compare>
392 {
393 public:
394 
395  Splay_Tree_Rk_Vtl(Compare && cmp = Compare())
397  {
398  // empty
399  }
400 
401  Splay_Tree_Rk_Vtl(Compare & cmp)
403  {
404  // empty
405  }
406 };
407 
408 
409 #endif /* TPL_SPLAY_TREE_H */
Key key_type
El tipo de clave que contiene el nodo.
Definition: tpl_splay_treeRk.H:35
Definition: tpl_splay_treeRk.H:391
#define LLINK(p)
Definition: tpl_binNode.H:196
#define RLINK(p)
Definition: tpl_binNode.H:201
Node * insert(Node *p)
Definition: tpl_splay_treeRk.H:165
bool is_empty() const
Retorna true si el treap está vacío.
Definition: tpl_splay_treeRk.H:280
#define COUNT(p)
Definition: tpl_binNodeXt.H:34
Node * rotate_to_right_xt(Node *p)
Definition: tpl_binNodeXt.H:757
void splay(const Key &key)
Definition: tpl_splay_treeRk.H:45
Definition: tpl_splay_treeRk.H:372
virtual ~GenTdSplayTreeRk()
Destructor.
Definition: tpl_splay_treeRk.H:132
Compare & get_compare()
Definition: tpl_splay_treeRk.H:41
size_t size() const
Retorna la cantidad de nodos que contiene el treap.
Definition: tpl_splay_treeRk.H:274
GenTdSplayTreeRk(Compare &__cmp)
Constructor.
Definition: tpl_splay_treeRk.H:113
Node * select(Node *r, const size_t &pos)
Definition: tpl_binNodeXt.H:89
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_splay_treeRk.H:38
std::pair< int, Node * > find_position(const Key &key)
Definition: tpl_splay_treeRk.H:344
Node * rotate_to_left_xt(Node *p)
Definition: tpl_binNodeXt.H:776
Node *& getRoot()
Get the top down splay tree's root.
Definition: tpl_splay_treeRk.H:266
#define KEY(p)
Definition: tpl_binNode.H:206
Node * select(const size_t &i)
Definition: tpl_splay_treeRk.H:364
Node * search(const Key &key)
Definition: tpl_splay_treeRk.H:206
Definition: tpl_splay_treeRk.H:21
std::pair< int, Node * > position(const Key &key)
Definition: tpl_splay_treeRk.H:297

Leandro Rabindranath León