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