aGrUM  0.16.0
binTreeNode_tpl.h
Go to the documentation of this file.
1 
30 #ifndef DOXYGEN_SHOULD_SKIP_THIS
31 
32 namespace gum {
33 
34  template < typename Val >
35  INLINE BinTreeNode< Val >::BinTreeNode(const Val& v) :
36  _val(v), _parent(0), _parent_dir(BinTreeDir::NO_PARENT) {
37  // for debugging purposes
38  GUM_CONSTRUCTOR(BinTreeNode);
39 
40  // set the children
41  _children[0] = nullptr;
42  _children[1] = nullptr;
43  }
44 
45  template < typename Val >
46  INLINE BinTreeNode< Val >::BinTreeNode(const BinTreeNode< Val >& from) :
48  // for debugging purposes
49  GUM_CONS_CPY(BinTreeNode);
50 
51  // set the children
52  _children[0] = nullptr;
53  _children[1] = nullptr;
54  }
55 
56  template < typename Val >
58  // for debugging purposes
59  GUM_DESTRUCTOR(BinTreeNode);
60 
61  // update the tree accordingly to the removal of this
62  if (_parent)
63  _parent->_children[static_cast< int >(_parent_dir)] =
64  nullptr; // parent_dir can not be NO_PARENT (... sure ?)
65 
66  if (_children[0]) {
67  _children[0]->_parent = nullptr;
68  _children[0]->_parent_dir = BinTreeDir::NO_PARENT;
69  }
70 
71  if (_children[1]) {
72  _children[1]->_parent = nullptr;
73  _children[1]->_parent_dir = BinTreeDir::NO_PARENT;
74  }
75  }
76 
80  template < typename Val >
81  INLINE BinTreeNode< Val >& BinTreeNode< Val >::
82  operator=(const BinTreeNode< Val >& from) {
83  // avoid self assignment
84  if (this != &from) {
85  GUM_OP_CPY(BinTreeNode);
86  _val = from._val;
87  }
88 
89  return *this;
90  }
91 
92  template < typename Val >
93  INLINE Val& BinTreeNode< Val >::value() {
94  return _val;
95  }
96 
97  template < typename Val >
98  INLINE Val& BinTreeNode< Val >::operator*() {
99  return _val;
100  }
101 
102  template < typename Val >
103  INLINE BinTreeNode< Val >* BinTreeNode< Val >::child(BinTreeDir dir) const {
104  return _children[static_cast< int >(dir)];
105  }
106 
107  template < typename Val >
108  INLINE BinTreeNode< Val >* BinTreeNode< Val >::leftChild() const {
109  return _children[static_cast< int >(BinTreeDir::LEFT_CHILD)];
110  }
111 
112  template < typename Val >
113  INLINE BinTreeNode< Val >* BinTreeNode< Val >::rightChild() const {
114  return _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
115  }
116 
117  template < typename Val >
118  INLINE BinTreeNode< Val >* BinTreeNode< Val >::parent() const {
119  return _parent;
120  }
121 
122  template < typename Val >
124  return _parent_dir;
125  }
126 
127  template < typename Val >
128  INLINE void BinTreeNode< Val >::insertLeftChild(BinTreeNode< Val >& new_child) {
129  if (new_child._parent) {
130  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
131  }
132 
133  if (_children[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
134  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
135  }
136 
137  // proceed to the chaining
138  new_child._parent = this;
139  new_child._parent_dir = BinTreeDir::LEFT_CHILD;
140  _children[static_cast< int >(BinTreeDir::LEFT_CHILD)] = &new_child;
141  }
142 
143  template < typename Val >
144  INLINE BinTreeNode< Val >* BinTreeNode< Val >::insertLeftChild(const Val& val) {
145  if (_children[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
146  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
147  }
148 
149  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
150 
151  // proceed to the chaining
152  new_child->_parent = this;
153  new_child->_parent_dir = BinTreeDir::LEFT_CHILD;
154  _children[static_cast< int >(BinTreeDir::LEFT_CHILD)] = new_child;
155 
156  return new_child;
157  }
158 
159  template < typename Val >
160  INLINE void BinTreeNode< Val >::insertRightChild(BinTreeNode< Val >& new_child) {
161  if (new_child._parent) {
162  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
163  }
164 
165  if (_children[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
166  GUM_ERROR(DuplicateElement, "this node already has a right child");
167  }
168 
169  // proceed to the chaining
170  new_child._parent = this;
171  new_child._parent_dir = BinTreeDir::RIGHT_CHILD;
172  _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = &new_child;
173  }
174 
175  template < typename Val >
176  INLINE BinTreeNode< Val >* BinTreeNode< Val >::insertRightChild(const Val& val) {
177  if (_children[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
178  GUM_ERROR(DuplicateElement, "this node already has a right child");
179  }
180 
181  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
182 
183  // proceed to the chaining
184  new_child->_parent = this;
185  new_child->_parent_dir = BinTreeDir::RIGHT_CHILD;
186  _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = new_child;
187 
188  return new_child;
189  }
190 
191  template < typename Val >
192  INLINE void BinTreeNode< Val >::insertChild(BinTreeNode< Val >& new_child,
193  BinTreeDir child_dir) {
194  if (new_child._parent) {
195  GUM_ERROR(DuplicateElement, "this child has already a parent");
196  }
197 
198  if (_children[static_cast< int >(child_dir)]) {
199  GUM_ERROR(DuplicateElement, "this node has already this child");
200  }
201 
202  // proceed to the chaining
203  new_child._parent = this;
204  new_child._parent_dir = child_dir;
205  _children[static_cast< int >(child_dir)] = &new_child;
206  }
207 
208  template < typename Val >
209  INLINE BinTreeNode< Val >*
210  BinTreeNode< Val >::insertChild(const Val& val, BinTreeDir child_dir) {
211  if (_children[static_cast< int >(child_dir)]) {
212  GUM_ERROR(DuplicateElement, "this node has already this child");
213  }
214 
215  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
216 
217  // proceed to the chaining
218  new_child->_parent = this;
219  new_child->_parent_dir = child_dir;
220  _children[static_cast< int >(child_dir)] = new_child;
221 
222  return new_child;
223  }
224 
225  template < typename Val >
226  INLINE void BinTreeNode< Val >::eraseLeftLink() {
227  if (_children[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
228  _children[static_cast< int >(BinTreeDir::LEFT_CHILD)]->_parent = nullptr;
229  _children[static_cast< int >(BinTreeDir::LEFT_CHILD)]->_parent_dir =
231  _children[static_cast< int >(BinTreeDir::LEFT_CHILD)] = nullptr;
232  }
233  }
234 
235  template < typename Val >
236  INLINE void BinTreeNode< Val >::eraseRightLink() {
237  if (_children[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
238  _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)]->_parent = nullptr;
239  _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)]->_parent_dir =
241  _children[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = nullptr;
242  }
243  }
244 
245  template < typename Val >
246  INLINE void BinTreeNode< Val >::eraseLink(BinTreeDir tree_dir) {
247  if (_children[static_cast< int >(tree_dir)]) {
248  _children[static_cast< int >(tree_dir)]->_parent = nullptr;
249  _children[static_cast< int >(tree_dir)]->_parent_dir = BinTreeDir::NO_PARENT;
250  _children[static_cast< int >(tree_dir)] = nullptr;
251  }
252  }
253 
254  template < typename Val >
255  INLINE BinTreeNode< Val >* BinTreeNode< Val >::leftmostNode() const {
256  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
257 
258  while (node->_children[static_cast< int >(BinTreeDir::LEFT_CHILD)])
259  node = node->_children[static_cast< int >(BinTreeDir::LEFT_CHILD)];
260 
261  return node;
262  }
263 
264  template < typename Val >
265  INLINE BinTreeNode< Val >* BinTreeNode< Val >::rightmostNode() const {
266  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
267 
268  while (node->_children[static_cast< int >(BinTreeDir::RIGHT_CHILD)])
269  node = node->_children[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
270 
271  return node;
272  }
273 
274  template < typename Val >
275  INLINE BinTreeNode< Val >* BinTreeNode< Val >::root() const {
276  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
277 
278  while (node->_parent)
279  node = node->_parent;
280 
281  return node;
282  }
283 
284 } // namespace gum
285 
286 #endif // DOXYGEN_SHOULD_SKIP_THIS
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.
Val _val
The value stored in a node of the tree.
Definition: binTreeNode.h:319
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< Val > * _children[2]
The children of the current node.
Definition: binTreeNode.h:328
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
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:37
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.
BinTreeDir _parent_dir
the direction to follow from the parent to reach the current node.
Definition: binTreeNode.h:325
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.
Val & operator*()
Alias for method value.
BinTreeNode< Val > * _parent
The parent of the node.
Definition: binTreeNode.h:322
BinTreeNode< Val > * insertRightChild(const Val &val)
Adds a new left child to the current node.
~BinTreeNode()
Class destructor.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
BinTreeNode< Val > * insertChild(const Val &val, BinTreeDir child_dir)
Adds a new child to the current node.