aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
splay.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Splay Trees header file.
25  *
26  * @author Karim Tekkal
27  */
28 
29 #ifndef GUM_SPLAY_H
30 #define GUM_SPLAY_H
31 
32 #include <iostream>
33 //#include <stdlib.h>
34 
35 #include <agrum/agrum.h>
36 #include <agrum/tools/core/hashTable.h>
37 
38 namespace gum {
39 
40  template < class Element >
41  class SplayBinaryNode;
42  template < class Element >
43  class SplayTree;
44 
45  /// Display the node
46 
47  template < typename Element >
48  INLINE std::ostream& operator<<(std::ostream& out,
49  const SplayBinaryNode< Element >& e);
50 
51  /// Display the tree
52 
53  template < typename Element >
54  INLINE std::ostream& operator<<(std::ostream& out,
55  const SplayTree< Element >& s);
56 
57  // =========================================================================
58  // === NODE ===
59  // =========================================================================
60  /**
61  * @class SplayBinaryNode
62  * @headerfile splay.h <agrum/tools/core/splay.h>
63  * @brief the nodes of splay trees
64  * @ingroup splaytree_group
65  *
66  * @author Karim Tekkal
67  *
68  * These file implements a data structure. A splay tree is a self-balancing
69  * binary search tree.
70  */
71  template < class Element >
72  class SplayBinaryNode {
73  public:
74  // ============================================================================
75  /// @name Accessors / Modifiers
76  // ============================================================================
77  /// @{
78 
79  /**
80  * @brief Position of the node.
81  * @return The position of the node into the tree.
82  */
83  int position() const;
84 
85  /**
86  * @brief Returns the element in the node.
87  * @return Returns the element in the node.
88  */
89  const Element& getElement() const;
90 
91  /**
92  * @brief Returns the left child.
93  * @return Returns the left child.
94  * @warning The returned value can be null.
95  */
96  const SplayBinaryNode< Element >* getFg() const;
97 
98  /**
99  * @brief Returns the right child.
100  * @return Returns the right child.
101  * @warning The returned value can be null.
102  */
103  const SplayBinaryNode< Element >* getFd() const;
104 
105  /// @}
106 
107  protected:
108  // ============================================================================
109  /// @name Constructors / Destructors
110  // ============================================================================
111  /// @{
112 
113  /**
114  * @brief Basic constructor: creates a node with a reference to the element.
115  * @param e The element in the node.
116  * @param addr TODO don't know what to do here.
117  * @param g The left child of the node, can be nullptr.
118  * @param d The right child of the node, can be nullptr.
119  * @param p The father of the node, can be nullptr if the node
120  * is the root of the tree.
121  */
122  SplayBinaryNode(const Element& e,
123  HashTable< Element, SplayBinaryNode< Element >* >& addr,
124  SplayBinaryNode* g = 0,
125  SplayBinaryNode* d = 0,
126  SplayBinaryNode* p = 0);
127 
128  /**
129  * @brief Copy constructor.
130  * @param from the src SplayBinaryNode
131  * @param addr TODO don't know what to do here.
132  */
133  SplayBinaryNode(const SplayBinaryNode< Element >& from,
134  HashTable< Element, SplayBinaryNode< Element >* >& addr);
135 
136  /**
137  * @brief A function used to perform copies.
138  * @param from the src SplayBinaryNode
139  * @param addr TODO don't know what to do here ..
140  */
141  void copy_(const SplayBinaryNode< Element >& from,
142  HashTable< Element, SplayBinaryNode< Element >* >& addr);
143 
144  /**
145  * @brief Class destructor.
146  */
147  ~SplayBinaryNode();
148 
149  /// @}
150  // ============================================================================
151  /// @name Accessors / Modifiers
152  // ============================================================================
153  /// @{
154 
155  /**
156  * @brief A right rotation, the node must have a father.
157  * @return Returns a pointer to the root of the sub-tree after rotation.
158  */
159  SplayBinaryNode< Element >* zig();
160 
161  /**
162  * @brief A left rotation, the node must hava a father.
163  * @return Returns a pointer to the root of the sub-tree after rotation.
164  */
165  SplayBinaryNode< Element >* zag();
166 
167  /**
168  * @brief A splay rotation, the node will be the root of the tree.
169  * @return Returns a pointer to the root of the sub-tree after rotation.
170  */
171  SplayBinaryNode< Element >* splay();
172 
173  /**
174  * @brief Concatenation of two trees.
175  * @param e The node to add.
176  * @param addr TODO Don't know what to do here.
177  * @return Returns the root of the created tree.
178  */
179  SplayBinaryNode< Element >*
180  join(const SplayBinaryNode< Element >* e,
181  HashTable< Element, SplayBinaryNode< Element >* >& addr);
182 
183  /// @}
184  // ============================================================================
185  /// @name Data Members
186  // ============================================================================
187  /// @{
188 
189  /// The content.
190  Element elt;
191 
192  /// The size of the sub-tree.
193  Size size;
194 
195  /// The left child.
196  SplayBinaryNode* fg;
197 
198  /// The right child.
199  SplayBinaryNode* fd;
200 
201  /// The father, nullptr for the root.
202  SplayBinaryNode* pere;
203 
204  /// @}
205 
206  /// Friendly with SplayTree
207  friend class SplayTree< Element >;
208 
209  /// Friendly to display
210  friend std::ostream& operator<<<>(std::ostream& out,
211  const SplayBinaryNode< Element >&);
212  };
213 
214  // ============================================================================
215  // === SPLAY TREE ===
216  // ============================================================================
217  /**
218  * @class SplayTree
219  * @headerfile splay.h <agrum/tools/core/splay.h>
220  * @brief A splay tree.
221  * @ingroup splaytree_group
222  * @ingroup basicstruct_group
223  *
224  * @warning an Element must be in just one Splay Tree, the behavior is
225  * unspecified else.
226  *
227  * @par Usage example:
228  * @code
229  * // Creating empty trees
230  * SplayTree<string> a;
231  *
232  * // Make a copy
233  * SplayTree<string> b(a);
234  *
235  * // Add an element
236  * a.insert("toto");
237  * a.insert("titi");
238  *
239  * // Get the first element
240  * a.front();
241  * // And the last
242  * a.back();
243  *
244  * // concatenate two trees
245  * a.join(b);
246  *
247  * // divide a tree at the third position, the first part is placed into a
248  * // the second into b.
249  * b = a.split(3);
250  *
251  * // Display the splay tree
252  * a.printTree();
253  *
254  * // Get the size
255  * a.size();
256  * @endcode
257  *
258  * @tparam Element The elements type.
259  */
260  template < class Element >
261  class SplayTree {
262  public:
263  // ============================================================================
264  /// @name Constructors / Destructors
265  // ============================================================================
266  /// @{
267 
268  /**
269  * @brief Basic constructor, make an empty splay tree.
270  */
271  SplayTree();
272 
273  /**
274  * @brief Basic constructor, make a splay tree with one element.
275  * @param e The element of the tree.
276  */
277  SplayTree(const Element& e);
278 
279  /**
280  * @brief Copy constructor.
281  * @param from The gum::SplayTree to copy.
282  */
283  SplayTree(const SplayTree& from);
284 
285  /**
286  * @brief Class destructor.
287  */
288  ~SplayTree();
289 
290  /// @}
291  // ============================================================================
292  /// @name Operators
293  // ============================================================================
294  /// @{
295 
296  /**
297  * @brief Assignment operator.
298  * @param from The gum::SplayTree to copy.
299  * @return This gum::SplayTree.
300  */
301  SplayTree< Element >& operator=(const SplayTree< Element >& from);
302 
303  /// @}
304  // ============================================================================
305  /// @name Methods
306  // ============================================================================
307  /// @{
308 
309  /**
310  * @brief Get the element at the position n.
311  * @param i The position of the element to return.
312  * @throw NotFound Raised if no element was found.
313  * @return Returns the element at the position n.
314  */
315  Element& operator[](const unsigned int i);
316 
317  /**
318  * @brief Get the element at the position n.
319  * @param i The position of the element to return.
320  * @throw NotFound Raised if no element was found.
321  * @return Returns the element at the position n.
322  */
323  const Element& operator[](const unsigned int i) const;
324 
325 
326  /**
327  * @brief Get the first element.
328  * @throw NotFound Raised if the splay tree is empty.
329  */
330  Element& front();
331 
332  /**
333  * @brief Get the last element.
334  * @throw NotFound Raised if the splay tree is empty.
335  */
336  Element& back();
337 
338  /**
339  * @brief Remove the first element.
340  */
341  void popFront();
342 
343  /**
344  * @brief Remove the last element.
345  */
346  void popBack();
347 
348  /**
349  * @brief Add an element in the first position.
350  * @param e The element to push.
351  */
352  void pushFront(const Element& e);
353 
354  /**
355  * @brief Add an element in the last position.
356  * @param e The element to push.
357  */
358  void pushBack(const Element& e);
359 
360  /**
361  * @brief Add an element to the tree.
362  * @param e The element to add.
363  */
364  void insert(const Element& e);
365 
366  /**
367  * @brief Concatenation of two trees.
368  * @param s The tree to add.
369  */
370  void join(const SplayTree< Element >& s);
371 
372 
373  /**
374  * @brief Divide the tree at the position.
375  *
376  * @warning all the elements less than e are stored into the tree and those
377  * who are greater than e in the returned tree.
378  *
379  * @param i The position of the element (e) for split.
380  * @return Returns a tree with all the elements greater than i.
381  */
382  SplayTree< Element > split(const int i);
383 
384 
385  /**
386  * @brief Divide the tree at the position.
387  * @param e the element for split
388  * @warning All the elements less than e are stored into the tree and those
389  * greater than e are in the returned tree
390  * @warning The element e is neither in the trees.
391  * @return Returns the tree with all value greather than e.
392  */
393  SplayTree< Element > split_by_val(const Element& e);
394 
395  /**
396  * @brief The number of elements in the tree.
397  * @return the size of the tree
398  */
399  Size size() const;
400 
401  /**
402  * @brief Test if the tree contains the element.
403  * @param e The element to test if it is in the splay tree.
404  * @return Returns true if e is in this splay tree.
405  */
406  bool contains(const Element& e) const;
407 
408  /// @}
409 
410  protected:
411  // ============================================================================
412  /// @name Data Menbers
413  // ============================================================================
414  /// @{
415 
416  /// Root of the tree
417  SplayBinaryNode< Element >* root;
418 
419  /// The hash table to find quickly the position of a node
420  HashTable< Element, SplayBinaryNode< Element >* > addr;
421 
422  /// @}
423 
424  /// a function used to perform copies
425  void copy_(const SplayTree< Element >&);
426 
427  /// Friendly to display
428  friend std::ostream& operator<<<>(std::ostream& out,
429  const SplayTree< Element >&);
430  };
431 
432 } /* namespace gum */
433 
434 // always include the tpl_.h as it contains only templates
435 #include <agrum/tools/core/splay_tpl.h>
436 
437 #endif /* GUM_SPLAY_H */