aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
binTreeNode.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  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #ifndef GUM_BIN_TREE_NODE_H
29 #define GUM_BIN_TREE_NODE_H
30 
31 #include <agrum/agrum.h>
32 
33 namespace gum {
34 
35  /// The direction of a given edge in a binary tree.
36  enum class BinTreeDir : char
37  {
38  LEFT_CHILD = 0,
39  RIGHT_CHILD = 1,
40  NO_PARENT = 2
41  };
42 
43  // ===========================================================================
44  // === GENERIC NODE FOR A BINARY TREE ===
45  // ===========================================================================
46 
47  /**
48  * @class BinTreeNode
49  * @headerfile binTreeNode.h <agrum/tools/core/binTreeNode.h>
50  * @brief Nodes of a binary trees.
51  * @ingroup basicstruct_group
52  *
53  * BinTreeNode is the base class for nodes of binary trees. It is equipped
54  * with the material to add nodes to or remove them from the tree. The class
55  * ensures that trees are always a coherent structure, that is, it is not
56  * possible to have a node X having, say, a left child, and this child having
57  * no parent or a parent different from X.
58  *
59  * @tparam Val The value's type storde in the gum::BinTreeNode.
60  *
61  * @par Usage example:
62  *
63  * @code
64  * // create a node containing an integer
65  * BinTreeNode<int> node1 (33);
66  *
67  * // get the integer contained in the node
68  * std::cerr << node1.value () << std::endl;
69  * std::cerr << *node1 << std::endl;
70  *
71  * // create a disconnected node containing the same value as node1
72  * BinTreeNode<int> node2 = node1;
73  * BinTreeNode<int> node3 (3); node3 = node1;
74  *
75  * // insert left and right children
76  * node1.insertLeftChild(node2);
77  * node1.insertRightChild(node3);
78  *
79  * BinTreeNode<int>* node4 = node2.insertLeftChild(3);
80  * BinTreeNode<int>* node5 = node2.insertRightChild(4);
81  *
82  * BinTreeNode<int>* node6 = node4.insertChild(5, GUM_BIN_TREE_LEFT_CHILD);
83  * BinTreeNode<int>* node7 = node4.insertChild(6, GUM_BIN_TREE_RIGHT_CHILD);
84  *
85  * BinTreeNode<int> node8 (55), node9(44);
86  * node3.insertChild(node8, GUM_BIN_TREE_LEFT_CHILD);
87  * node3.insertChild(node9, GUM_BIN_TREE_RIGHT_CHILD);
88  *
89  * // get the parents and children
90  * BinTreeNode<int>* node8 = node.parent();
91  * node8 = node1.leftChild();
92  * node8 = node1.rightChild();
93  * node8 = node1.child(gum::GUM_BIN_TREE_LEFT_CHILD);
94  * node8 = node1.child(gum::GUM_BIN_TREE_RIGHT_CHILD);
95  *
96  * // remove links between parents and children
97  * node1.eraseLeftLink(); // erase the connection between node1 and node2
98  * node1.eraseRightLink(); // erase the connection between node1 and node3
99  * node2.eraseLink(gum::GUM_BIN_TREE_LEFT_CHILD); // erase (node2,node4)
100  * node2.eraseLink(gum::GUM_BIN_TREE_RIGHT_CHILD); // erase (node2;node5)
101  * @endcode
102  */
103  template < typename Val >
104  class BinTreeNode {
105  public:
106  // ============================================================================
107  /// @name Class constructors and destructors
108  // ============================================================================
109  /// @{
110 
111  /**
112  * @brief Basic constructor: a node without parent nor children.
113  * @param v The value stored in the node.
114  */
115  BinTreeNode(const Val& v);
116 
117  /**
118  * @brief copy constructor: creates a new disconnected node with the same
119  * value as "from".
120  *
121  * @warning Although the new node contains the same value as from, it has
122  * no parent, nor any children, even if from has some.
123  *
124  * @param from The node to copy.
125  */
126  BinTreeNode(const BinTreeNode< Val >& from);
127 
128  /**
129  * @brief Class destructor.
130  *
131  * In addition to removing the node, this method updates appropriately
132  * its parent and children
133  */
134  ~BinTreeNode();
135 
136  /// @}
137  // ============================================================================
138  /// @name Class operators
139  // ============================================================================
140  /// @{
141 
142  /**
143  * @brief Copy operator: copy the value of from into this.
144  *
145  * However, this does not change the current connections (parents and
146  * children) of this.
147  *
148  * @param from The node to copy.
149  * @return Returns this gum::BinTreeNode.
150  */
151  BinTreeNode< Val >& operator=(const BinTreeNode< Val >& from);
152 
153  /**
154  * @brief Alias for method value.
155  * @return Return the value stored in this node.
156  */
157  Val& operator*();
158 
159  /// @}
160  // ============================================================================
161  /// @name Class accessors and modifiers
162  // ============================================================================
163  /// @{
164 
165  /**
166  * @brief Returns the value stored in a node of the binary search tree.
167  * @return The value stored in this node.
168  */
169  Val& value();
170 
171  /**
172  * @brief Returns the given child of a node.
173  * @warning If the child does not exists, the method returns a 0 pointer.
174  * @param dir The direction where we loog for a child.
175  * @return Returns the child of a node.
176  */
177  BinTreeNode< Val >* child(BinTreeDir dir) const;
178 
179  /**
180  * @brief Returns the given child of a node.
181  * @warning If the child does not exists, the method returns a 0 pointer.
182  * @return Retuns the left child of this node.
183  */
184  BinTreeNode< Val >* leftChild() const;
185 
186  /**
187  * @brief Returns the given child of a node.
188  * @warning If the child does not exists, the method returns a 0 pointer.
189  * @return Retuns the right child of this node.
190  */
191  BinTreeNode< Val >* rightChild() const;
192 
193  /**
194  * @brief Returns the parent of a node.
195  * @warning If the parent does not exists, the method returns a 0 pointer.
196  * @return Returns the parent of this node.
197  */
198  BinTreeNode< Val >* parent() const;
199 
200  /**
201  * @brief Returns the direction of the edge parent->current node, if any.
202  * @return Returns the direction of the edge parent->current node, if any.
203  */
204  BinTreeDir parentDir() const;
205 
206  /**
207  * @brief Adds a new left child to the current node.
208  * @warning the new child is created on the C++ heap (i.e., using a
209  * dynamic memory allocation)
210  * @param val The value to store in the new child.
211  * @return a pointer on the new created child
212  * @throw DuplicateElement if the current node had already a left child
213  */
214  BinTreeNode< Val >* insertLeftChild(const Val& val);
215 
216  /**
217  * @brief Adds a new left child to the current node.
218  * @param new_child The child to add.
219  * @throw DuplicateElement Raised if the current node had already a left
220  * child or if new_child already has a parent.
221  */
222  void insertLeftChild(BinTreeNode< Val >& new_child);
223 
224  /**
225  * @brief Adds a new left child to the current node.
226  * @warning the new child is created on the C++ heap (i.e., using a
227  * dynamic memory allocation)
228  * @param val The value to store in the new child.
229  * @return a pointer on the new created child
230  * @throw DuplicateElement if the current node had already a left child
231  */
232  BinTreeNode< Val >* insertRightChild(const Val& val);
233 
234  /**
235  * @brief Adds a new right child to the current node.
236  * @param new_child The child to add.
237  * @throw DuplicateElement Raised if the current node had already a right
238  * child or if new_child already has a parent.
239  */
240  void insertRightChild(BinTreeNode< Val >& new_child);
241 
242  /**
243  * @brief Adds a new child to the current node.
244  * @param val The value to add.
245  * @param child_dir The direction where to add the child.
246  * @return Returns a pointer on the new created child
247  * @throw DuplicateElement Raised if the current node had already a child
248  * in the child_dir subtree.
249  */
250  BinTreeNode< Val >* insertChild(const Val& val, BinTreeDir child_dir);
251 
252  /**
253  * @brief Adds a new child to the current node.
254  * @param new_child The child to add.
255  * @param child_dir The direction where to add the child.
256  * @throw DuplicateElement Raised if the current node had already a child
257  * in the child_dir direction or if new_child already has a parent .
258  */
259  void insertChild(BinTreeNode< Val >& new_child, BinTreeDir child_dir);
260 
261  /**
262  * @brief Remove the link between the current node and its left child.
263  *
264  * Note that only the link is removed, i.e., the left child is not removed
265  * itself nor, a fortiori, the left subtree of the current node. If there
266  * is no left child, the method does nothing. In particular, it does not
267  * raise any exception.
268  */
269  void eraseLeftLink();
270 
271  /**
272  * @brief Remove the link between the current node and its right child.
273  *
274  * Note that only the link is removed, i.e., the right child is not removed
275  * itself nor, a fortiori, the right subtree of the current node. If there
276  * is no right child, the method does nothing. In particular, it does not
277  * raise any exception.
278  */
279  void eraseRightLink();
280 
281  /**
282  * @brief Remove the link between the current node and one of its children.
283  *
284  * Note that only the link is removed, i.e., the child is not removed
285  * itself nor, a fortiori, its subtree. If the child does not exist, the
286  * method does nothing. In particular, it does not raise any exception.
287  *
288  * @param tree_dir The direction where to remove the link.
289  */
290  void eraseLink(BinTreeDir tree_dir);
291 
292  /**
293  * @brief Returns the leftmost node of the current tree.
294  *
295  * If there is no left child, the method returns this.
296  *
297  * @return The left most node in the current tree.
298  */
299  BinTreeNode< Val >* leftmostNode() const;
300 
301  /**
302  * @brief Returns the rightmost node of the current tree.
303  *
304  * If there is no right child, the method returns this.
305  *
306  * @return The right most node in the current tree.
307  */
308  BinTreeNode< Val >* rightmostNode() const;
309 
310  /**
311  * @brief Returns the top ancestor of the current tree.
312  *
313  * If the current node has no parent, the the method returns this.
314  *
315  * @return Returns the top ancestor of the current tree.
316  */
317  BinTreeNode< Val >* root() const;
318 
319  /// @}
320 
321  protected:
322  /// The value stored in a node of the tree.
323  Val val_;
324 
325  /// The parent of the node.
327 
328  /// the direction to follow from the parent to reach the current node.
330 
331  /// The children of the current node.
332  BinTreeNode< Val >* children_[2];
333  };
334 
335 } /* namespace gum */
336 
337 
338 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS
339 extern template class gum::BinTreeNode< int >;
340 #endif
341 
342 
343 // always include the implementation of the templates
344 #include <agrum/tools/core/binTreeNode_tpl.h>
345 
346 #endif // GUM_BIN_TREE_NODE_H
void insertChild(BinTreeNode< Val > &new_child, BinTreeDir child_dir)
Adds a new child to the current node.
BinTreeDir parent_dir_
the direction to follow from the parent to reach the current node.
Definition: binTreeNode.h:329
BinTreeNode(const BinTreeNode< Val > &from)
copy constructor: creates a new disconnected node with the same value as "from".
BinTreeNode< Val > * child(BinTreeDir dir) const
Returns the given child of a node.
Val & value()
Returns the value stored in a node of the binary search tree.
BinTreeNode< Val > * leftmostNode() const
Returns the leftmost node of the current tree.
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
BinTreeNode< Val > * insertLeftChild(const Val &val)
Adds a new left child to the current node.
void eraseLeftLink()
Remove the link between the current node and its left child.
BinTreeNode< Val > * leftChild() const
Returns the given child of a node.
BinTreeNode(const Val &v)
Basic constructor: a node without parent nor children.
void eraseLink(BinTreeDir tree_dir)
Remove the link between the current node and one of its children.
BinTreeDir
The direction of a given edge in a binary tree.
Definition: binTreeNode.h:36
BinTreeNode< Val > & operator=(const BinTreeNode< Val > &from)
Copy operator: copy the value of from into this.
BinTreeNode< Val > * rightmostNode() const
Returns the rightmost node of the current tree.
BinTreeNode< Val > * parent_
The parent of the node.
Definition: binTreeNode.h:326
Val val_
The value stored in a node of the tree.
Definition: binTreeNode.h:323
void eraseRightLink()
Remove the link between the current node and its right child.
BinTreeDir parentDir() const
Returns the direction of the edge parent->current node, if any.
BinTreeNode< Val > * root() const
Returns the top ancestor of the current tree.
BinTreeNode< Val > * rightChild() const
Returns the given child of a node.
BinTreeNode< Val > * parent() const
Returns the parent of a node.
BinTreeNode< Val > * children_[2]
The children of the current node.
Definition: binTreeNode.h:332
Nodes of a binary trees.
Definition: binTreeNode.h:104
Val & operator*()
Alias for method value.
BinTreeNode< Val > * insertRightChild(const Val &val)
Adds a new left child to the current node.
void insertLeftChild(BinTreeNode< Val > &new_child)
Adds a new left child to the current node.
~BinTreeNode()
Class destructor.
void insertRightChild(BinTreeNode< Val > &new_child)
Adds a new right child to the current node.
BinTreeNode< Val > * insertChild(const Val &val, BinTreeDir child_dir)
Adds a new child to the current node.