aGrUM  0.16.0
binSearchTree_tpl.h
Go to the documentation of this file.
1 
30 #include <sstream>
31 #include <string>
32 
34 #include <agrum/core/exceptions.h>
35 
36 #ifndef DOXYGEN_SHOULD_SKIP_THIS
37 
38 namespace gum {
39 
40  // ===========================================================================
41  // ===========================================================================
42  // === GENERIC BINARY SEARCH TREE ITERATORS ===
43  // ===========================================================================
44  // ===========================================================================
45 
46  template < typename Val, class Cmp, class Node >
48  _node(0), _next_node(0), _prev_node(0), _parent(0), _left_child(0),
49  _right_child(0), _tree(0), _next_iter(0) {
50  GUM_CONSTRUCTOR(BinSearchTreeIterator);
51  }
52 
53  template < typename Val, class Cmp, class Node >
55  const BinSearchTreeIterator< Val, Cmp, Node >& from) :
56  _node(from._node),
59  _right_child(from._right_child), _tree(from._tree) {
60  GUM_CONS_CPY(BinSearchTreeIterator);
61 
62  if (_tree) {
63  _next_iter = _tree->_iterator_list;
64  _tree->_iterator_list = this;
65  } else
66  _next_iter = 0;
67  }
68 
69  template < typename Val, class Cmp, class Node >
72  const Node* current_node,
73  bool add_to_iterator_list) {
74  // remember: we do not check here whether the iterator already belongs to
75  // a tree. We assume that it is not so.
76 
77  _tree = const_cast< BinSearchTree< Val, Cmp, Node >* >(tree);
78  _node = const_cast< Node* >(current_node);
79 
80  if (add_to_iterator_list && _tree) {
81  _next_iter = _tree->_iterator_list;
82  _tree->_iterator_list = this;
83  }
84  }
85 
86  template < typename Val, class Cmp, class Node >
88  if (_tree) {
89  BinSearchTreeIterator< Val, Cmp, Node >*iter, *prev_iter = 0;
90 
91  for (iter = _tree->_iterator_list; iter != this && iter;
92  prev_iter = iter, iter = iter->_next_iter) {}
93 
94  if (iter) {
95  if (prev_iter)
96  prev_iter->_next_iter = _next_iter;
97  else
98  _tree->_iterator_list = _next_iter;
99  }
100  }
101  }
102 
103  template < typename Val, class Cmp, class Node >
105  GUM_DESTRUCTOR(BinSearchTreeIterator);
106 
107  // remove the iterator from its tree iterator's list
108  _detachFromTree();
109  }
110 
111  template < typename Val, class Cmp, class Node >
113  // remove the iterator from its tree iterator's list
114  _detachFromTree();
115 
116  // reset the iterator
117  _node = 0;
118  _next_node = 0;
119  _prev_node = 0;
120  _parent = 0;
121  _left_child = 0;
122  _right_child = 0;
123  _tree = 0;
124  _next_iter = 0;
125  }
126 
127  template < typename Val, class Cmp, class Node >
128  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
130  operator=(const BinSearchTreeIterator< Val, Cmp, Node >& from) {
131  // avoid self assignment
132  if (this != &from) {
133  GUM_OP_CPY(BinSearchTreeIterator);
134 
135  // if from and this belong to different trees, detach this from its
136  // current tree
137  if (from._tree != _tree) {
138  _detachFromTree();
139  _tree = from._tree;
140 
141  if (_tree) {
142  _next_iter = _tree->_iterator_list;
143  _tree->_iterator_list = this;
144  } else
145  _next_iter = 0;
146  }
147 
148  // make the iterators point to the same element
149  _node = from._node;
150  _next_node = from._next_node;
151  _prev_node = from._prev_node;
152  _parent = from._parent;
153  _left_child = from._left_child;
154  _right_child = from._right_child;
155  }
156 
157  return *this;
158  }
159 
160  template < typename Val, class Cmp, class Node >
161  INLINE const Val& BinSearchTreeIterator< Val, Cmp, Node >::operator*() const {
162  if (_node) return _node->value();
163 
164  GUM_ERROR(UndefinedIteratorValue,
165  "the iterator does not point to a node of the binary tree");
166  }
167 
168  template < typename Val, class Cmp, class Node >
169  INLINE Node* BinSearchTree< Val, Cmp, Node >::_minNode(Node* node) const {
170  Node* prevNode = 0;
171 
172  for (; node; prevNode = node, node = node->leftChild()) {}
173 
174  return prevNode;
175  }
176 
177  template < typename Val, class Cmp, class Node >
178  INLINE Node* BinSearchTree< Val, Cmp, Node >::_maxNode(Node* node) const {
179  Node* prevNode = 0;
180 
181  for (; node; prevNode = node, node = node->rightChild()) {}
182 
183  return prevNode;
184  }
185 
186  template < typename Val, class Cmp, class Node >
187  INLINE Node* BinSearchTree< Val, Cmp, Node >::_succNode(Node* node) const {
188  if (!node) return 0;
189 
190  if (node->rightChild()) return _minNode(node->rightChild());
191 
192  Node* par = node->parent();
193 
194  while (par && (node->parentDir() == BinTreeDir::RIGHT_CHILD)) {
195  node = par;
196  par = par->parent();
197  }
198 
199  return par;
200  }
201 
202  template < typename Val, class Cmp, class Node >
203  INLINE Node* BinSearchTree< Val, Cmp, Node >::_prevNode(Node* node) const {
204  if (!node) return 0;
205 
206  if (node->leftChild()) return _maxNode(node->leftChild());
207 
208  Node* par = node->parent();
209 
210  while (par && (node->parentDir() == BinTreeDir::LEFT_CHILD)) {
211  node = par;
212  par = par->parent();
213  }
214 
215  return par;
216  }
217 
218  template < typename Val, class Cmp, class Node >
219  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
221  // if there is a current node, use it to compute the next node, else use
222  // directly _next_node (this case obtains when the iterator was pointing
223  // toward a node that has been deleted before we use operator++)
224  _node = _node ? _tree->_succNode(_node) : _next_node;
225 
226  if (!_node) {
227  _next_node = 0;
228  _prev_node = 0;
229  _parent = 0;
230  _left_child = 0;
231  _right_child = 0;
232  }
233 
234  return *this;
235  }
236 
237  template < typename Val, class Cmp, class Node >
238  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
240  // if there is a current node, use it to compute the preceding node, else
241  // use
242  // directly _prev_node (this case obtains when the iterator was pointing
243  // toward a node that has been deleted before we use operator--)
244  _node = _node ? _tree->_prevNode(_node) : _prev_node;
245 
246  if (!_node) {
247  _next_node = 0;
248  _prev_node = 0;
249  _parent = 0;
250  _left_child = 0;
251  _right_child = 0;
252  }
253 
254  return *this;
255  }
256 
257  template < typename Val, class Cmp, class Node >
259  operator==(const BinSearchTreeIterator< Val, Cmp, Node >& from) const {
260  if (_node)
261  return (_node == from._node);
262  else
263  return ((_node == from._node) && (_tree == from._tree)
264  && (_next_node == from._next_node) && (_prev_node == from._prev_node)
265  && (_parent == from._parent) && (_left_child == from._left_child)
266  && (_right_child == from._right_child));
267  }
268 
269  template < typename Val, class Cmp, class Node >
271  operator!=(const BinSearchTreeIterator< Val, Cmp, Node >& from) const {
272  if (_node)
273  return (_node != from._node);
274  else
275  return ((_node != from._node) || (_tree != from._tree)
276  || (_next_node != from._next_node) || (_prev_node != from._prev_node)
277  || (_parent != from._parent) || (_left_child != from._left_child)
278  || (_right_child != from._right_child));
279  }
280 
281  template < typename Val, class Cmp, class Node >
282  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
284  // if there is a current node, use it to compute its parent node, else use
285  // directly _parent (this case obtains when the iterator was pointing
286  // toward a node that has been deleted before we use operation up)
287  _node = _node ? _node->parent() : _parent;
288 
289  if (!_node) {
290  _next_node = 0;
291  _prev_node = 0;
292  _parent = 0;
293  _left_child = 0;
294  _right_child = 0;
295  }
296 
297  return *this;
298  }
299 
300  template < typename Val, class Cmp, class Node >
301  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
303  // if there is a current node, use it to compute its left child, else use
304  // directly _left_child (this case obtains when the iterator was pointing
305  // toward a node that has been deleted before we use operation downLeft)
306  _node = _node ? _node->leftChild() : _left_child;
307 
308  if (!_node) {
309  _next_node = 0;
310  _prev_node = 0;
311  _parent = 0;
312  _left_child = 0;
313  _right_child = 0;
314  }
315 
316  return *this;
317  }
318 
319  template < typename Val, class Cmp, class Node >
320  INLINE BinSearchTreeIterator< Val, Cmp, Node >&
322  // if there is a current node, use it to compute its right child, else use
323  // directly _right_child (this case obtains when the iterator was pointing
324  // toward a node that has been deleted before we use operation downRight)
325  _node = _node ? _node->rightChild() : _right_child;
326 
327  if (!_node) {
328  _next_node = 0;
329  _prev_node = 0;
330  _parent = 0;
331  _left_child = 0;
332  _right_child = 0;
333  }
334 
335  return *this;
336  }
337 
338  // ===========================================================================
339  // ===========================================================================
340  // === GENERIC BINARY SEARCH TREE ===
341  // ===========================================================================
342  // ===========================================================================
343 
344  template < typename Val, class Cmp, class Node >
345  BinSearchTree< Val, Cmp, Node >::BinSearchTree(bool uniqueness_policy) :
346  _root(0), _iterator_list(0), _uniqueness_policy(uniqueness_policy),
347  _nb_elements(0) {
348  GUM_CONSTRUCTOR(BinSearchTree);
349  _iter_end._initialize(this, 0, false);
350  }
351 
352  template < typename Val, class Cmp, class Node >
354  const BinSearchTree< Val, Cmp, Node >& from) :
355  _root(0),
356  _iterator_list(0), _uniqueness_policy(from._uniqueness_policy) {
357  // for debugging purposes
358  GUM_CONS_CPY(BinSearchTree);
359 
360  // copy the content of BinSearchTree "from"
361  _root = _copy(from._root);
362  _nb_elements = from._nb_elements;
363 
364  // initialize the end/rend iterator
365  _iter_end._initialize(this, 0, false);
366  }
367 
368  template < typename Val, class Cmp, class Node >
370  // first we clear all the iterators, i.e., we detach them from the tree
371  for (iterator *iter = _iterator_list, *next_iter = 0; iter; iter = next_iter) {
372  next_iter = iter->_next_iter;
373  iter->clear();
374  }
375 
376  // now, delete the whole tree
377  _deleteSubTree(_root);
378  _root = 0;
379  _nb_elements = 0;
380 
381  // note that there is no need to redefined end/rend as they do not rely
382  // on the content of the tree
383  }
384 
385  template < typename Val, class Cmp, class Node >
388  // avoid self assignment
389  if (this != &from) {
390  // for debugging purposes
391  GUM_OP_CPY(BinSearchTree);
392 
393  // if the tree is not currently empty, remove it
394  clear();
395 
396  // copy binary tree "from"
397  _uniqueness_policy = from._uniqueness_policy;
398  _root = _copy(from._root); // note that we can copy from's tree structure
399  // as from and this have the same ordering _cmp
400  _nb_elements = from._nb_elements;
401 
402  // note that we do not need to update the end/rend iterator as, besides
403  // field _tree, no other field is related to the current tree (i.e., all
404  // _*_node are set to 0
405  }
406 
407  return *this;
408  }
409 
410  template < typename Val, class Cmp, class Node >
412  // for debugging purposes
413  GUM_DESTRUCTOR(BinSearchTree);
414 
415  // clear all the iterators and remove all nodes
416  clear();
417  }
418 
419  template < typename Val, class Cmp, class Node >
421  Node* parent,
422  BinTreeDir dir) {
423  // if there is no node to copy, abort
424  if (!node) return 0;
425 
426  // create the copy of node
427  Node* new_node = new Node(*node);
428 
429  if (parent) parent->insertChild(*new_node, dir);
430 
431  // if necessary, create the left and right subgraphs
432  _copy(node->leftChild(), new_node, BinTreeDir::LEFT_CHILD);
433  _copy(node->rightChild(), new_node, BinTreeDir::RIGHT_CHILD);
434 
435  return new_node;
436  }
437 
438  template < typename Val, class Cmp, class Node >
440  // if there is no node to remove, return
441  if (!node) return;
442 
443  // delete the left and right subgraphs
444  _deleteSubTree(node->leftChild());
445  _deleteSubTree(node->rightChild());
446 
447  // delete the node itself
448  delete node;
449  }
450 
451  template < typename Val, class Cmp, class Node >
452  INLINE Node* BinSearchTree< Val, Cmp, Node >::_insert(const Val& val) {
453  // if the tree is not empty, search the binary search tree to know
454  // where the node should be inserted
455  if (_root) {
456  Node* node = _root;
457 
458  while (true) {
459  if (_cmp(val, node->value()))
460  if (!node->leftChild()) {
461  // here we are on a leaf => insert the new node
462  ++_nb_elements;
463  return node->insertLeftChild(val);
464  } else {
465  node = node->leftChild();
466  }
467  else if (_cmp(node->value(), val) || !_uniqueness_policy)
468  if (!node->rightChild()) {
469  // here we are on a leaf => insert the new node
470  ++_nb_elements;
471  return node->insertRightChild(val);
472  } else {
473  node = node->rightChild();
474  }
475  else {
476  // here we found a node with the same key and the uniqueness policy
477  // is set. So we should raise an exception
478  GUM_ERROR(DuplicateElement,
479  "Val " << val << " already in the binary search tree");
480  }
481  }
482  }
483 
484  // here the tree is empty, just create a new node
485  _root = new Node(val);
486  ++_nb_elements;
487  return _root;
488  }
489 
490  template < typename Val, class Cmp, class Node >
491  INLINE const Val& BinSearchTree< Val, Cmp, Node >::insert(const Val& val) {
492  return _insert(val)->value();
493  }
494 
495  template < typename Val, class Cmp, class Node >
496  INLINE const Val& BinSearchTree< Val, Cmp, Node >::rootValue() const {
497  if (_root == 0) {
498  GUM_ERROR(NotFound, "no value in an empty Binary Search tree");
499  }
500 
501  return _root->value();
502  }
503 
504  template < typename Val, class Cmp, class Node >
505  INLINE const Val& BinSearchTree< Val, Cmp, Node >::minValue() const {
506  if (_root == 0) {
507  GUM_ERROR(NotFound, "no minimal value in an empty Binary Search tree");
508  }
509 
510  return _minNode(_root)->value();
511  }
512 
513  template < typename Val, class Cmp, class Node >
514  INLINE const Val& BinSearchTree< Val, Cmp, Node >::maxValue() const {
515  if (_root == 0) {
516  GUM_ERROR(NotFound, "no maximal value in an empty Binary Search tree");
517  }
518 
519  return _maxNode(_root)->value();
520  }
521 
522  template < typename Val, class Cmp, class Node >
523  INLINE Node* BinSearchTree< Val, Cmp, Node >::_getNode(const Val& val) const {
524  // if the tree is not empty, search the binary search tree to know
525  // where the node could be
526  if (_root) {
527  Node* node = _root;
528 
529  while (true) {
530  if (_cmp(val, node->value())) {
531  if (!node->leftChild())
532  return 0;
533  else
534  node = node->leftChild();
535  } else if (_cmp(node->value(), val)) {
536  if (!node->rightChild())
537  return 0;
538  else
539  node = node->rightChild();
540  } else
541  return node;
542  }
543  } else {
544  return 0;
545  }
546  }
547 
548  template < typename Val, class Cmp, class Node >
549  INLINE bool BinSearchTree< Val, Cmp, Node >::contains(const Val& val) const {
550  return (_getNode(val) != 0);
551  }
552 
553  template < typename Val, class Cmp, class Node >
555  return _nb_elements;
556  }
557 
558  template < typename Val, class Cmp, class Node >
559  INLINE bool BinSearchTree< Val, Cmp, Node >::empty() const {
560  return (_nb_elements == 0);
561  }
562 
563  template < typename Val, class Cmp, class Node >
564  const std::string BinSearchTree< Val, Cmp, Node >::toString() const {
565  bool deja = false;
566  std::stringstream stream;
567  stream << "[";
568 
569  for (const_iterator iter = begin(); iter != end(); ++iter, deja = true) {
570  if (deja) stream << " , ";
571 
572  stream << *iter;
573  }
574 
575  stream << "]";
576 
577  return stream.str();
578  }
579 
580  template < typename Val, class Cmp, class Node >
582  return _uniqueness_policy;
583  }
584 
585  template < typename Val, class Cmp, class Node >
586  INLINE void
588  _uniqueness_policy = new_policy;
589  }
590 
591  template < typename Val, class Cmp, class Node >
592  INLINE BinSearchTreeIterator< Val, Cmp, Node >
594  BinSearchTreeIterator< Val, Cmp, Node > iter;
595  iter._initialize(this, _minNode(_root), true);
596  return iter;
597  }
598 
599  template < typename Val, class Cmp, class Node >
600  INLINE BinSearchTreeIterator< Val, Cmp, Node >
602  BinSearchTreeIterator< Val, Cmp, Node > iter;
603  iter._initialize(this, _minNode(_root), true);
604  return iter;
605  }
606 
607  template < typename Val, class Cmp, class Node >
608  INLINE BinSearchTreeIterator< Val, Cmp, Node >
610  BinSearchTreeIterator< Val, Cmp, Node > iter;
611  iter._initialize(this, _maxNode(_root), true);
612  return iter;
613  }
614 
615  template < typename Val, class Cmp, class Node >
616  INLINE BinSearchTreeIterator< Val, Cmp, Node >
618  BinSearchTreeIterator< Val, Cmp, Node > iter;
619  iter._initialize(this, _maxNode(_root), true);
620  return iter;
621  }
622 
623  template < typename Val, class Cmp, class Node >
624  INLINE const BinSearchTreeIterator< Val, Cmp, Node >&
626  return _iter_end;
627  }
628 
629  template < typename Val, class Cmp, class Node >
630  INLINE const BinSearchTreeIterator< Val, Cmp, Node >&
632  return _iter_end;
633  }
634 
635  template < typename Val, class Cmp, class Node >
636  INLINE const BinSearchTreeIterator< Val, Cmp, Node >&
638  return _iter_end;
639  }
640 
641  template < typename Val, class Cmp, class Node >
642  INLINE const BinSearchTreeIterator< Val, Cmp, Node >&
644  return _iter_end;
645  }
646 
647  template < typename Val, class Cmp, class Node >
648  INLINE BinSearchTreeIterator< Val, Cmp, Node >
650  BinSearchTreeIterator< Val, Cmp, Node > iter;
651  iter._initialize(this, _root, true);
652  return iter;
653  }
654 
655  template < typename Val, class Cmp, class Node >
656  INLINE BinSearchTreeIterator< Val, Cmp, Node >
658  BinSearchTreeIterator< Val, Cmp, Node > iter;
659  iter._initialize(this, _root, true);
660  return iter;
661  }
662 
663  template < typename Val, class Cmp, class Node >
664  void BinSearchTree< Val, Cmp, Node >::_erase(Node* node) {
665  if (!node) return;
666 
667  // update all the iterators pointing to node that they should point
668  // elsewhere
669  __updateEraseIterators(node);
670 
671  // update the number of elements contained in the tree
672  --_nb_elements;
673 
674  // now remove the node from the tree:
675 
676  // if the node has no children, then just remove it
677  if (!node->leftChild() && !node->rightChild()) {
678  // if the node was the only one in the tree, then the tree becomes empty
679  if (!node->parent()) _root = 0;
680 
681  // note that, when node has a parent, there is no need to remove the
682  // link between node and this parent: this will be taken care of by
683  // node's destructor.
684  }
685  // if there is just a right child
686  else if (!node->leftChild()) {
687  // just relink the right child with the parent (if any)
688  if (!node->parent()) {
689  // in this case, no need to remove the link between "node" and its
690  // child:
691  // this will be taken care of by the destructor of "node"
692  _root = node->rightChild();
693  } else {
694  Node * parent = node->parent(), *child = node->rightChild();
695  BinTreeDir dir = node->parentDir();
696  parent->eraseLink(dir);
697  node->eraseRightLink();
698  parent->insertChild(*child, dir);
699  }
700  }
701  // if there is just a left child
702  else if (!node->rightChild()) {
703  // just relink the left child with the parent (if any)
704  if (!node->parent()) {
705  // in this case, no need to remove the link between "node" and its
706  // child:
707  // this will be taken care of by the destructor of "node"
708  _root = node->leftChild();
709  } else {
710  Node * parent = node->parent(), *child = node->leftChild();
711  BinTreeDir dir = node->parentDir();
712  parent->eraseLink(dir);
713  node->eraseLeftLink();
714  parent->insertChild(*child, dir);
715  }
716  }
717  // ok, here there are two children
718  else {
719  __eraseWithTwoChildren(node);
720  }
721 
722  // now we shall physically remove node from memory
723  delete node;
724  }
725 
726  template < typename Val, class Cmp, class Node >
728  // the idea is to get the successor of "node" and substitute "node" by
729  // it. As "node" has two children, we are sure that the successor is one
730  // of node's descendants. Moreover, by its very definition, this
731  // successor has no left child. Hence, two cases can obtain:
732  // 1/ the successor is precisely node's right child. In this case, we just
733  // have to make node's left child be the left child of the successor,
734  // and node's parent be the successor's parent, and the tree is again
735  // a binary search tree.
736  // 2/ the successor is not node's right child. In this case, we know that
737  // the successor has a parent different from node and that the
738  // successor
739  // is a left child of this parent. We just need to put the right child
740  // of the successor (if any) as the left child of its parent, and to
741  // replace "node" by the successor.
742  Node* successor = _succNode(node);
743 
744  if (successor == node->rightChild()) { // proceed to case 1:
745  Node* left_child = node->leftChild();
746  node->eraseLeftLink();
747  node->eraseRightLink();
748  successor->insertLeftChild(*left_child);
749 
750  if (!node->parent()) {
751  // in this case, no need to remove the link between "node" and the
752  // successor: this will be taken care of by the destructor of "node"
753  _root = successor;
754  } else {
755  // rechain node's parent with its successor
756  BinTreeDir par_dir = node->parentDir();
757  Node* parent = node->parent();
758  parent->eraseLink(par_dir);
759  parent->insertChild(*successor, par_dir);
760  }
761  } else { // proceed to case 2:
762  Node* parent = successor->parent();
763  parent->eraseLeftLink();
764 
765  if (successor->rightChild()) {
766  Node* succ_child = successor->rightChild();
767  successor->eraseRightLink();
768  parent->insertLeftChild(*succ_child);
769  }
770 
771  Node *left = node->leftChild(), *right = node->rightChild();
772  node->eraseLeftLink();
773  node->eraseRightLink();
774  successor->insertLeftChild(*left);
775  successor->insertRightChild(*right);
776 
777  if (!node->parent()) {
778  _root = successor;
779  } else {
780  // rechain node's parent with its successor
781  BinTreeDir par_dir = node->parentDir();
782  Node* parent = node->parent();
783  parent->eraseLink(par_dir);
784  parent->insertChild(*successor, par_dir);
785  }
786  }
787  }
788 
789  template < typename Val, class Cmp, class Node >
790  INLINE void BinSearchTree< Val, Cmp, Node >::erase(const Val& val) {
791  Node* n = _getNode(val);
792 
793  if (n == nullptr)
794  GUM_ERROR(gum::NotFound, "Value \"" << val << "\" not found");
795 
796  _erase(n);
797  }
798 
799  template < typename Val, class Cmp, class Node >
800  INLINE void BinSearchTree< Val, Cmp, Node >::erase(const iterator& iter) {
801  _erase(iter._node);
802  }
803 
804  template < typename Val, class Cmp, class Node >
806  for (iterator* iter = _iterator_list; iter; iter = iter->_next_iter) {
807  // if the iterator points toward the node to be deleted, make its _node
808  // field point to 0 and update accordingly its other fields
809  if (iter->_node == node) {
810  iter->_node = 0;
811  iter->_next_node = _succNode(node);
812  iter->_prev_node = _prevNode(node);
813  iter->_parent = node->parent();
814  iter->_left_child = node->leftChild();
815  iter->_right_child = node->rightChild();
816  } else if (!iter->_node) {
817  if (iter->_next_node == node) iter->_next_node = _succNode(node);
818 
819  if (iter->_prev_node == node) iter->_prev_node = _prevNode(node);
820 
821  if (iter->_parent == node) iter->_parent = node->parent();
822 
823  if (iter->_left_child == node) iter->_left_child = node->leftChild();
824 
825  if (iter->_right_child == node) iter->_right_child = node->rightChild();
826  }
827  }
828  }
829 
830 } // namespace gum
831 
832 #endif // DOXYGEN_SHOULD_SKIP_THIS
virtual ~BinSearchTree()
Class destructor.
BinSearchTree< Val, Cmp, Node > * _tree
The binary search tree pointed to by the iterator.
BinSearchTreeIterator< Val, Cmp, Node > & operator--()
Point the iterator to the preceding value in the binary search tree.
Node * _getNode(const Val &val) const
Returns the node containing a given value.
Node * _maxNode(Node *node) const
Returns the greatest node w.r.t.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Size size() const
Returns the number of elements in the binary search tree.
Node * _left_child
The left child to be used when _node=0 and leftdown() is applied.
BinSearchTreeIterator< Val, Cmp, Node > & downRight()
Makes the iterator move to the right child of the node it points to.
Node * _next_node
The next node to be used when _node=0 (if a ++ operator is applied).
const Val & insert(const Val &val)
Creates a copy of the value, insert it in the tree and returns the copy value.
bool operator==(const BinSearchTreeIterator< Val, Cmp, Node > &from) const
Checks whether two iterators are pointing toward identical elements.
void clear()
Detach the iterator from its current tree (if any) and reset it.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
BinSearchTreeIterator()
Class Constructors and Destructors.
iterator rbegin()
Reverse iterator.
bool operator!=(const BinSearchTreeIterator< Val, Cmp, Node > &from) const
Checks whether two iterators are pointing toward different elements.
Node * _copy(Node *root_from, Node *parent=0, BinTreeDir dir=BinTreeDir::LEFT_CHILD)
A method for recursively copying the contents of a BinSearchTree.
void _deleteSubTree(Node *node)
A method for recursively deleting a subtree of the gum::BinSearchTree.
BinTreeDir
The direction of a given edge in a binary tree.
Definition: binTreeNode.h:37
bool empty() const
Indicates whether the gum::BinSearchTree search tree is empty.
iterator root()
Returns an iterator at the root of the tree.
const Val & minValue() const
Returns the value of the leftmost node with the minimal key in the tree.
BinSearchTreeIterator< Val, Cmp, Node > & operator++()
Point the iterator to the next value in the binary search tree.
const Val & rootValue() const
Returns the value of the root of the tree.
Node * _parent
The parent to be used when _node=0 (if operation up is applied).
const Val & maxValue() const
Returns the value of the rightmost node with the maximal key in the tree.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
BinSearchTreeIterator< Val, Cmp, Node > & up()
Makes the iterator move to its parent node.
Node * _right_child
The right child to be used when _node=0 and rightdown() is applied.
BinSearchTree(bool uniqueness_policy=false)
Basic constructor: returns an empty binary search tree.
Node * _node
The current node pointed to by the iterator.
bool uniquenessPolicy() const
Returns the current uniqueness policy.
virtual Node * _insert(const Val &val)
Creates a copy of the value, insert it in the gum::BinSearchTree and returns the copy value...
void __updateEraseIterators(Node *node)
Update all iterators when a given node is deleted.
void clear()
Removes all the elements from the gum::BinSearchTree.
BinSearchTreeIterator< Val, Cmp, Node > & downLeft()
Makes the iterator move to the left child of the node it points to.
virtual const std::string toString() const
Displays the content of the tree, in increasing order w.r.t.
const iterator & rend()
Reverse end iterator.
void erase(const Val &val)
Erase the leftmost node with the given (key,val) pair.
void setUniquenessPolicy(const bool new_policy)
Enables the user to change dynamically the policy for checking whether there can exist several identi...
Node * _prev_node
The preceding node to be used when _node=0 (if a – operator is applied).
const iterator & end()
End iterator.
const Val & operator*() const
Returns the value pointed to by the iterator.
BinSearchTree< Val, Cmp, Node > & operator=(const BinSearchTree< Val, Cmp, Node > &from)
Copy operator.
BinSearchTreeIterator< Val, Cmp, Node > * _next_iter
The next iterator in the list of iterators of the binSearchTree.
Node * _succNode(Node *node) const
Returns the next node according to the weak ordering Cmp.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
friend class BinSearchTree< Val, Cmp, Node >
To speed-up accesses.
BinSearchTreeIterator< Val, Cmp, Node > & operator=(const BinSearchTreeIterator< Val, Cmp, Node > &from)
Class operators.
~BinSearchTreeIterator()
Class destructor.
bool contains(const Val &val) const
Returns true if the gum::BinSearchTree contains the value.
virtual void _erase(Node *node)
Erase the node passed in argument.
void _initialize(const BinSearchTree< Val, Cmp, Node > *tree, const Node *current_node, bool add_to_iterator_list)
A function called to initialize an iterator.
iterator begin()
Begin iterator.
void _detachFromTree()
a method to detach the current iterator from its tree&#39;s iterator&#39;s list.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
Node * _minNode(Node *node) const
Returns the smallest node w.r.t.
void __eraseWithTwoChildren(Node *node)
Erase a node with two children.
Node * _prevNode(Node *node) const
Returns the previous node according to weak ordering Cmp.