aGrUM  0.21.0
a C++ library for (probabilistic) graphical models
binTreeNode_tpl.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 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) :
37 
38  // set the children
39  children_[0] = nullptr;
40  children_[1] = nullptr;
41  }
42 
43  template < typename Val >
47 
48  // set the children
49  children_[0] = nullptr;
50  children_[1] = nullptr;
51  }
52 
53  template < typename Val >
56 
57  // update the tree accordingly to the removal of this
58  if (parent_)
59  parent_->children_[static_cast< int >(parent_dir_)]
60  = nullptr; // parent_dir can not be NO_PARENT (... sure ?)
61 
62  if (children_[0]) {
63  children_[0]->parent_ = nullptr;
65  }
66 
67  if (children_[1]) {
68  children_[1]->parent_ = nullptr;
70  }
71  }
72 
73  /** @brief copy operator: copy the value of from into this. However, this
74  * does not change the current connections (parents and children) of this. */
75 
76  template < typename Val >
78  // avoid self assignment
79  if (this != &from) {
81  val_ = from.val_;
82  }
83 
84  return *this;
85  }
86 
87  template < typename Val >
88  INLINE Val& BinTreeNode< Val >::value() {
89  return val_;
90  }
91 
92  template < typename Val >
94  return val_;
95  }
96 
97  template < typename Val >
99  return children_[static_cast< int >(dir)];
100  }
101 
102  template < typename Val >
103  INLINE BinTreeNode< Val >* BinTreeNode< Val >::leftChild() const {
104  return children_[static_cast< int >(BinTreeDir::LEFT_CHILD)];
105  }
106 
107  template < typename Val >
108  INLINE BinTreeNode< Val >* BinTreeNode< Val >::rightChild() const {
109  return children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
110  }
111 
112  template < typename Val >
113  INLINE BinTreeNode< Val >* BinTreeNode< Val >::parent() const {
114  return parent_;
115  }
116 
117  template < typename Val >
119  return parent_dir_;
120  }
121 
122  template < typename Val >
124  if (new_child.parent_) {
125  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST")
126  }
127 
128  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
129  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST")
130  }
131 
132  // proceed to the chaining
133  new_child.parent_ = this;
135  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = &new_child;
136  }
137 
138  template < typename Val >
140  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
141  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST")
142  }
143 
144  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
145 
146  // proceed to the chaining
147  new_child->parent_ = this;
149  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = new_child;
150 
151  return new_child;
152  }
153 
154  template < typename Val >
156  if (new_child.parent_) {
157  GUM_ERROR(DuplicateElement, "this child already has a parent in the BST")
158  }
159 
160  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
161  GUM_ERROR(DuplicateElement, "this node already has a right child")
162  }
163 
164  // proceed to the chaining
165  new_child.parent_ = this;
167  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = &new_child;
168  }
169 
170  template < typename Val >
172  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
173  GUM_ERROR(DuplicateElement, "this node already has a right child")
174  }
175 
176  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
177 
178  // proceed to the chaining
179  new_child->parent_ = this;
181  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = new_child;
182 
183  return new_child;
184  }
185 
186  template < typename Val >
188  if (new_child.parent_) { GUM_ERROR(DuplicateElement, "this child has already a parent") }
189 
190  if (children_[static_cast< int >(child_dir)]) {
191  GUM_ERROR(DuplicateElement, "this node has already this child")
192  }
193 
194  // proceed to the chaining
195  new_child.parent_ = this;
197  children_[static_cast< int >(child_dir)] = &new_child;
198  }
199 
200  template < typename Val >
202  if (children_[static_cast< int >(child_dir)]) {
203  GUM_ERROR(DuplicateElement, "this node has already this child")
204  }
205 
206  BinTreeNode< Val >* new_child = new BinTreeNode< Val >(val);
207 
208  // proceed to the chaining
209  new_child->parent_ = this;
211  children_[static_cast< int >(child_dir)] = new_child;
212 
213  return new_child;
214  }
215 
216  template < typename Val >
217  INLINE void BinTreeNode< Val >::eraseLeftLink() {
218  if (children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]) {
219  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)]->parent_ = nullptr;
221  children_[static_cast< int >(BinTreeDir::LEFT_CHILD)] = nullptr;
222  }
223  }
224 
225  template < typename Val >
226  INLINE void BinTreeNode< Val >::eraseRightLink() {
227  if (children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]) {
228  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)]->parent_ = nullptr;
230  children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)] = nullptr;
231  }
232  }
233 
234  template < typename Val >
236  if (children_[static_cast< int >(tree_dir)]) {
237  children_[static_cast< int >(tree_dir)]->parent_ = nullptr;
238  children_[static_cast< int >(tree_dir)]->parent_dir_ = BinTreeDir::NO_PARENT;
239  children_[static_cast< int >(tree_dir)] = nullptr;
240  }
241  }
242 
243  template < typename Val >
245  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
246 
247  while (node->children_[static_cast< int >(BinTreeDir::LEFT_CHILD)])
248  node = node->children_[static_cast< int >(BinTreeDir::LEFT_CHILD)];
249 
250  return node;
251  }
252 
253  template < typename Val >
255  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
256 
257  while (node->children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)])
258  node = node->children_[static_cast< int >(BinTreeDir::RIGHT_CHILD)];
259 
260  return node;
261  }
262 
263  template < typename Val >
264  INLINE BinTreeNode< Val >* BinTreeNode< Val >::root() const {
265  BinTreeNode< Val >* node = const_cast< BinTreeNode< Val >* >(this);
266 
267  while (node->parent_)
268  node = node->parent_;
269 
270  return node;
271  }
272 
273 } // namespace gum
274 
275 #endif // DOXYGEN_SHOULD_SKIP_THIS
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643