36 #ifndef DOXYGEN_SHOULD_SKIP_THIS 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) {
53 template <
typename Val,
class Cmp,
class Node >
55 const BinSearchTreeIterator< Val, Cmp, Node >& from) :
64 _tree->_iterator_list =
this;
69 template <
typename Val,
class Cmp,
class Node >
72 const Node* current_node,
73 bool add_to_iterator_list) {
78 _node =
const_cast< Node*
>(current_node);
80 if (add_to_iterator_list &&
_tree) {
82 _tree->_iterator_list =
this;
86 template <
typename Val,
class Cmp,
class Node >
89 BinSearchTreeIterator< Val, Cmp, Node >*iter, *prev_iter = 0;
91 for (iter =
_tree->_iterator_list; iter !=
this && iter;
92 prev_iter = iter, iter = iter->_next_iter) {}
103 template <
typename Val,
class Cmp,
class Node >
111 template <
typename Val,
class Cmp,
class Node >
127 template <
typename Val,
class Cmp,
class Node >
128 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
130 operator=(
const BinSearchTreeIterator< Val, Cmp, Node >& from) {
137 if (from._tree !=
_tree) {
143 _tree->_iterator_list =
this;
160 template <
typename Val,
class Cmp,
class Node >
162 if (_node)
return _node->value();
165 "the iterator does not point to a node of the binary tree");
168 template <
typename Val,
class Cmp,
class Node >
172 for (; node; prevNode = node, node = node->leftChild()) {}
177 template <
typename Val,
class Cmp,
class Node >
181 for (; node; prevNode = node, node = node->rightChild()) {}
186 template <
typename Val,
class Cmp,
class Node >
190 if (node->rightChild())
return _minNode(node->rightChild());
192 Node* par = node->parent();
202 template <
typename Val,
class Cmp,
class Node >
206 if (node->leftChild())
return _maxNode(node->leftChild());
208 Node* par = node->parent();
218 template <
typename Val,
class Cmp,
class Node >
219 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
237 template <
typename Val,
class Cmp,
class Node >
238 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
257 template <
typename Val,
class Cmp,
class Node >
259 operator==(
const BinSearchTreeIterator< Val, Cmp, Node >& from)
const {
261 return (_node == from._node);
263 return ((_node == from._node) && (
_tree == from._tree)
269 template <
typename Val,
class Cmp,
class Node >
271 operator!=(
const BinSearchTreeIterator< Val, Cmp, Node >& from)
const {
273 return (_node != from._node);
275 return ((_node != from._node) || (
_tree != from._tree)
281 template <
typename Val,
class Cmp,
class Node >
282 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
287 _node = _node ? _node->parent() :
_parent;
300 template <
typename Val,
class Cmp,
class Node >
301 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
319 template <
typename Val,
class Cmp,
class Node >
320 INLINE BinSearchTreeIterator< Val, Cmp, Node >&
344 template <
typename Val,
class Cmp,
class Node >
346 _root(0), _iterator_list(0), _uniqueness_policy(uniqueness_policy),
348 GUM_CONSTRUCTOR(BinSearchTree);
349 _iter_end._initialize(
this, 0,
false);
352 template <
typename Val,
class Cmp,
class Node >
356 _iterator_list(0), _uniqueness_policy(from._uniqueness_policy) {
358 GUM_CONS_CPY(BinSearchTree);
361 _root = _copy(from._root);
362 _nb_elements = from._nb_elements;
365 _iter_end._initialize(
this, 0,
false);
368 template <
typename Val,
class Cmp,
class Node >
371 for (iterator *iter = _iterator_list, *next_iter = 0; iter; iter = next_iter) {
372 next_iter = iter->_next_iter;
377 _deleteSubTree(_root);
385 template <
typename Val,
class Cmp,
class Node >
391 GUM_OP_CPY(BinSearchTree);
397 _uniqueness_policy = from._uniqueness_policy;
398 _root = _copy(from._root);
400 _nb_elements = from._nb_elements;
410 template <
typename Val,
class Cmp,
class Node >
413 GUM_DESTRUCTOR(BinSearchTree);
419 template <
typename Val,
class Cmp,
class Node >
427 Node* new_node =
new Node(*node);
429 if (parent) parent->insertChild(*new_node, dir);
438 template <
typename Val,
class Cmp,
class Node >
444 _deleteSubTree(node->leftChild());
445 _deleteSubTree(node->rightChild());
451 template <
typename Val,
class Cmp,
class Node >
459 if (_cmp(val, node->value()))
460 if (!node->leftChild()) {
463 return node->insertLeftChild(val);
465 node = node->leftChild();
467 else if (_cmp(node->value(), val) || !_uniqueness_policy)
468 if (!node->rightChild()) {
471 return node->insertRightChild(val);
473 node = node->rightChild();
479 "Val " << val <<
" already in the binary search tree");
485 _root =
new Node(val);
490 template <
typename Val,
class Cmp,
class Node >
492 return _insert(val)->value();
495 template <
typename Val,
class Cmp,
class Node >
498 GUM_ERROR(NotFound,
"no value in an empty Binary Search tree");
501 return _root->value();
504 template <
typename Val,
class Cmp,
class Node >
507 GUM_ERROR(NotFound,
"no minimal value in an empty Binary Search tree");
510 return _minNode(_root)->value();
513 template <
typename Val,
class Cmp,
class Node >
516 GUM_ERROR(NotFound,
"no maximal value in an empty Binary Search tree");
519 return _maxNode(_root)->value();
522 template <
typename Val,
class Cmp,
class Node >
530 if (_cmp(val, node->value())) {
531 if (!node->leftChild())
534 node = node->leftChild();
535 }
else if (_cmp(node->value(), val)) {
536 if (!node->rightChild())
539 node = node->rightChild();
548 template <
typename Val,
class Cmp,
class Node >
550 return (_getNode(val) != 0);
553 template <
typename Val,
class Cmp,
class Node >
558 template <
typename Val,
class Cmp,
class Node >
560 return (_nb_elements == 0);
563 template <
typename Val,
class Cmp,
class Node >
566 std::stringstream stream;
569 for (const_iterator iter = begin(); iter != end(); ++iter, deja =
true) {
570 if (deja) stream <<
" , ";
580 template <
typename Val,
class Cmp,
class Node >
582 return _uniqueness_policy;
585 template <
typename Val,
class Cmp,
class Node >
588 _uniqueness_policy = new_policy;
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);
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);
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);
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);
623 template <
typename Val,
class Cmp,
class Node >
624 INLINE
const BinSearchTreeIterator< Val, Cmp, Node >&
629 template <
typename Val,
class Cmp,
class Node >
630 INLINE
const BinSearchTreeIterator< Val, Cmp, Node >&
635 template <
typename Val,
class Cmp,
class Node >
636 INLINE
const BinSearchTreeIterator< Val, Cmp, Node >&
641 template <
typename Val,
class Cmp,
class Node >
642 INLINE
const BinSearchTreeIterator< Val, Cmp, Node >&
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);
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);
663 template <
typename Val,
class Cmp,
class Node >
669 __updateEraseIterators(node);
677 if (!node->leftChild() && !node->rightChild()) {
679 if (!node->parent()) _root = 0;
686 else if (!node->leftChild()) {
688 if (!node->parent()) {
692 _root = node->rightChild();
694 Node * parent = node->parent(), *child = node->rightChild();
696 parent->eraseLink(dir);
697 node->eraseRightLink();
698 parent->insertChild(*child, dir);
702 else if (!node->rightChild()) {
704 if (!node->parent()) {
708 _root = node->leftChild();
710 Node * parent = node->parent(), *child = node->leftChild();
712 parent->eraseLink(dir);
713 node->eraseLeftLink();
714 parent->insertChild(*child, dir);
719 __eraseWithTwoChildren(node);
726 template <
typename Val,
class Cmp,
class Node >
742 Node* successor = _succNode(node);
744 if (successor == node->rightChild()) {
745 Node* left_child = node->leftChild();
746 node->eraseLeftLink();
747 node->eraseRightLink();
748 successor->insertLeftChild(*left_child);
750 if (!node->parent()) {
757 Node* parent = node->parent();
758 parent->eraseLink(par_dir);
759 parent->insertChild(*successor, par_dir);
762 Node* parent = successor->parent();
763 parent->eraseLeftLink();
765 if (successor->rightChild()) {
766 Node* succ_child = successor->rightChild();
767 successor->eraseRightLink();
768 parent->insertLeftChild(*succ_child);
771 Node *left = node->leftChild(), *right = node->rightChild();
772 node->eraseLeftLink();
773 node->eraseRightLink();
774 successor->insertLeftChild(*left);
775 successor->insertRightChild(*right);
777 if (!node->parent()) {
782 Node* parent = node->parent();
783 parent->eraseLink(par_dir);
784 parent->insertChild(*successor, par_dir);
789 template <
typename Val,
class Cmp,
class Node >
791 Node* n = _getNode(val);
799 template <
typename Val,
class Cmp,
class Node >
804 template <
typename Val,
class Cmp,
class Node >
806 for (iterator* iter = _iterator_list; iter; iter = iter->_next_iter) {
809 if (iter->_node == node) {
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);
819 if (iter->_prev_node == node) iter->_prev_node = _prevNode(node);
821 if (iter->_parent == node) iter->_parent = node->parent();
823 if (iter->_left_child == node) iter->_left_child = node->leftChild();
825 if (iter->_right_child == node) iter->_right_child = node->rightChild();
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.
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.
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.
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's iterator's list.
#define GUM_ERROR(type, msg)
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.