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_tree.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_binNode.H>
15 # include <tpl_binNodeUtils.H>
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 headnode;
30  Node * head, *& root;
31  Compare & cmp;
32 
33 public:
34 
36  typedef Key key_type;
37 
39  Compare & key_comp() { return cmp; }
40 
42  Compare & get_compare() { return key_comp(); }
43 
46  void splay(const Key & key)
47  {
48  Node headNode;
49  Node * l = &headNode;
50  Node * r = &headNode;
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(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(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  /* reassembling of sub trees in one with current as root */
90  RLINK(l) = LLINK(t);
91  LLINK(r) = RLINK(t);
92  LLINK(t) = headNode.getR();
93  RLINK(t) = headNode.getL();
94 
95  root = t;
96  }
97 
99  GenTdSplayTree(Compare & __cmp)
100  : head(&headnode), root(headnode.getR()), cmp(__cmp)
101  {
102  // Empty
103  }
104 
105  GenTdSplayTree(Compare && __cmp)
106  : head(&headnode), root(headnode.getR()), cmp(__cmp)
107  {
108  // Empty
109  }
110 
111  void swap(GenTdSplayTree & tree)
112  {
113  std::swap(root, tree.root);
114  std::swap(cmp, tree.cmp);
115  }
116 
118  virtual ~GenTdSplayTree() { /* empty */ }
119 
120 private:
121 
122  Node * __insert(Node * p)
123  {
124  if (cmp(KEY(p), KEY(root)))
125  { /* root is predecessor of p */
126  LLINK(p) = LLINK(root);
127  RLINK(p) = root;
128  LLINK(root) = Node::NullPtr;
129  }
130  else
131  { /* root is successor of p */
132  RLINK(p) = RLINK(root);
133  LLINK(p) = root;
134  RLINK(root) = Node::NullPtr;
135  }
136  return root = p; // inserted node become root
137  }
138 
139 public:
140 
147  Node * insert(Node * p)
148  {
149  I(p != Node::NullPtr);
150  I(LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr);
151 
152  /* test insertion in empty tree */
153  if (root == Node::NullPtr)
154  return root = p;
155 
156  const Key & key = KEY(p);
157 
158  splay(key);
159 
160  if (are_equals<Key, Compare>(KEY(root), key, cmp))
161  return NULL; // item is already in tree
162 
163  return __insert(p);
164  }
165 
166  Node * insert_dup(Node * p)
167  {
168  I(p != Node::NullPtr);
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  splay(KEY(p));
176 
177  return __insert(p);
178  }
179 
187  Node * search(const Key & key)
188  {
189  if (root == Node::NullPtr)
190  return NULL;
191 
192  splay(key);
193 
194  return are_equals<Key, Compare>(KEY(root), key) ? root : NULL;
195  }
196 
197  Node * search_or_insert(Node * p)
198  {
199  if (root == Node::NullPtr)
200  return root = p;
201 
202  const Key & key = KEY(p);
203  splay(key);
204  if (are_equals<Key, Compare>(key, KEY(root), cmp))
205  return root;
206 
207  return __insert(p);
208  }
209 
219  Node * remove(const Key & key)
220  {
221  if (root == Node::NullPtr)
222  return NULL;
223 
224  splay(key);
225 
226  if (no_equals<Key, Compare>(KEY(root), key, cmp))
227  return NULL; /* key not found */
228 
229  Node * ret_val = root; /* store node to delete */
230 
231  if (LLINK(root) == Node::NullPtr)
232  root = RLINK(root);
233  else
234  {
235  Node * p = RLINK(root);
236  root = LLINK(root);
237  splay(key);
238  RLINK(root) = p;
239  }
240 
241  ret_val->reset();
242 
243  return ret_val;
244  }
245 
247  Node *& getRoot()
248  {
249  return root;
250  }
251 
252  bool verify() const { return true; }
253 };
254 
255 
256  template <typename Key, class Compare = Aleph::less<Key>>
257 class Splay_Tree : public GenTdSplayTree<BinNode, Key, Compare>
258 {
259 public:
260 
261  Splay_Tree(Compare && cmp = Compare())
262  : GenTdSplayTree<BinNode, Key, Compare> (std::move(cmp))
263  {
264  // empty
265  }
266 
267  Splay_Tree(Compare & cmp)
269  {
270  // empty
271  }
272 };
273 
274 
275  template <typename Key, class Compare = Aleph::less<Key>>
276 class Splay_Tree_Vtl : public GenTdSplayTree<BinNodeVtl, Key, Compare>
277 {
278 public:
279 
280  Splay_Tree_Vtl(Compare && cmp = Compare())
282  {
283  // empty
284  }
285 
286  Splay_Tree_Vtl(Compare & cmp)
288  {
289  // empty
290  }
291 };
292 
293 
294 #endif /* TPL_SPLAY_TREE_H */
Node * rotate_to_left(Node *p)
Definition: tpl_binNodeUtils.H:2422
void splay(const Key &key)
Definition: tpl_splay_tree.H:46
#define LLINK(p)
Definition: tpl_binNode.H:196
Node *& getRoot()
Get the top down splay tree's root.
Definition: tpl_splay_tree.H:247
#define RLINK(p)
Definition: tpl_binNode.H:201
Definition: tpl_splay_tree.H:257
Node * insert(Node *p)
Definition: tpl_splay_tree.H:147
Definition: tpl_splay_tree.H:21
Node * rotate_to_right(Node *p)
Definition: tpl_binNodeUtils.H:2375
Compare & key_comp()
Retorna una referencia al criterio de comparación.
Definition: tpl_splay_tree.H:39
Key key_type
El tipo de clave que contiene el nodo.
Definition: tpl_splay_tree.H:36
Definition: tpl_splay_tree.H:276
Node * search(const Key &key)
Definition: tpl_splay_tree.H:187
#define KEY(p)
Definition: tpl_binNode.H:206
virtual ~GenTdSplayTree()
Destructor.
Definition: tpl_splay_tree.H:118
Compare & get_compare()
Definition: tpl_splay_tree.H:42
GenTdSplayTree(Compare &__cmp)
Constructor.
Definition: tpl_splay_tree.H:99

Leandro Rabindranath León