aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
binTreeNode_tpl.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 Node class for various binary search trees
25  *
26  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #ifndef DOXYGEN_SHOULD_SKIP_THIS
30 
31 namespace gum {
32 
33  template < typename Val >
34  INLINE BinTreeNode< Val >::BinTreeNode(const Val& v) :
36  // for debugging purposes
38 
39  // set the children
40  children_[0] = nullptr;
41  children_[1] = nullptr;
42  }
43 
44  template < typename Val >
47  // for debugging purposes
49 
50  // set the children
51  children_[0] = nullptr;
52  children_[1] = nullptr;
53  }
54 
55  template < typename Val >
57  // for debugging purposes
59 
60  // update the tree accordingly to the removal of this
61  if (parent_)
62  parent_->children_[static_cast< int >(parent_dir_)]
63  = nullptr; // parent_dir can not be NO_PARENT (... sure ?)
64 
65  if (children_[0]) {
66  children_[0]->parent_ = nullptr;
68  }
69 
70  if (children_[1]) {
71  children_[1]->parent_ = nullptr;
73  }
74  }
75 
76  /** @brief copy operator: copy the value of from into this. However, this
77  * does not change the current connections (parents and children) of this. */
78 
79  template < typename Val >
81  BinTreeNode< Val >::operator=(const BinTreeNode< Val >& from) {
82  // avoid self assignment
83  if (this != &from) {
85  val_ = from.val_;
86  }
87 
88  return *this;
89  }
90 
91  template < typename Val >
92  INLINE Val& BinTreeNode< Val >::value() {
93  return val_;
94  }
95 
96  template < typename Val >
98  return val_;
99  }
100 
101  template < typename Val >
103  return children_[static_cast< int >(dir)];
104  }
105 
106  template < typename Val >
107  INLINE BinTreeNode< Val >* BinTreeNode< Val >::leftChild() const {
108  return children_[static_cast< int >(BinTreeDir::LEFT_CHILD)];
109  }
110 
111  template < typename Val >
112  INLINE BinTreeNode< Val >* BinTreeNode< Val >::rightChild() const {
113  return children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
114  }
115 
116  template < typename Val >
117  INLINE BinTreeNode< Val >* BinTreeNode< Val >::parent() const {
118  return parent_;
119  }
120 
121  template < typename Val >
123  return parent_dir_;
124  }
125 
126  template < typename Val >
128  if (new_child.parent_) {
129  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
130  }
131 
132  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
133  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
134  }
135 
136  // proceed to the chaining
137  new_child.parent_ = this;
139  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = &new_child;
140  }
141 
142  template < typename Val >
144  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
145  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
146  }
147 
148  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
149 
150  // proceed to the chaining
151  new_child->parent_ = this;
153  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = new_child;
154 
155  return new_child;
156  }
157 
158  template < typename Val >
160  if (new_child.parent_) {
161  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST");
162  }
163 
164  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
165  GUM_ERROR(DuplicateElement, "this node already has a right child");
166  }
167 
168  // proceed to the chaining
169  new_child.parent_ = this;
171  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = &new_child;
172  }
173 
174  template < typename Val >
176  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
177  GUM_ERROR(DuplicateElement, "this node already has a right child");
178  }
179 
180  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
181 
182  // proceed to the chaining
183  new_child->parent_ = this;
185  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = new_child;
186 
187  return new_child;
188  }
189 
190  template < typename Val >
193  if (new_child.parent_) {
194  GUM_ERROR(DuplicateElement, "this child has already a parent");
195  }
196 
197  if (children_[static_cast< int >(child_dir)]) {
198  GUM_ERROR(DuplicateElement, "this node has already this child");
199  }
200 
201  // proceed to the chaining
202  new_child.parent_ = this;
204  children_[static_cast< int >(child_dir)] = &new_child;
205  }
206 
207  template < typename Val >
210  if (children_[static_cast< int >(child_dir)]) {
211  GUM_ERROR(DuplicateElement, "this node has already this child");
212  }
213 
214  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
215 
216  // proceed to the chaining
217  new_child->parent_ = this;
219  children_[static_cast< int >(child_dir)] = new_child;
220 
221  return new_child;
222  }
223 
224  template < typename Val >
225  INLINE void BinTreeNode< Val >::eraseLeftLink() {
226  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
227  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]->parent_ = nullptr;
228  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]->parent_dir_
230  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = nullptr;
231  }
232  }
233 
234  template < typename Val >
235  INLINE void BinTreeNode< Val >::eraseRightLink() {
236  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
237  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]->parent_ = nullptr;
238  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]->parent_dir_
240  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = nullptr;
241  }
242  }
243 
244  template < typename Val >
246  if (children_[static_cast< int >(tree_dir)]) {
247  children_[static_cast< int >(tree_dir)]->parent_ = nullptr;
248  children_[static_cast< int >(tree_dir)]->parent_dir_ = BinTreeDir::NO_PARENT;
249  children_[static_cast< int >(tree_dir)] = nullptr;
250  }
251  }
252 
253  template < typename Val >
255  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
256 
257  while (node->children_[static_cast< int >(BinTreeDir::LEFT_CHILD)])
258  node = node->children_[static_cast< int >(BinTreeDir::LEFT_CHILD)];
259 
260  return node;
261  }
262 
263  template < typename Val >
265  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
266 
267  while (node->children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)])
268  node = node->children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
269 
270  return node;
271  }
272 
273  template < typename Val >
274  INLINE BinTreeNode< Val >* BinTreeNode< Val >::root() const {
275  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
276 
277  while (node->parent_)
278  node = node->parent_;
279 
280  return node;
281  }
282 
283 } // namespace gum
284 
285 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669