57#ifndef DOXYGEN_SHOULD_SKIP_THIS
67 template <
typename Val,
class Cmp,
class Node >
69 node_(nullptr), next_node_(nullptr), prev_node_(nullptr), parent_(nullptr),
70 left_child_(nullptr), right_child_(nullptr), tree_(nullptr), next_iter_(nullptr) {
71 GUM_CONSTRUCTOR(BinSearchTreeIterator);
74 template <
typename Val,
class Cmp,
class Node >
75 BinSearchTreeIterator< Val, Cmp, Node >::BinSearchTreeIterator(
77 node_(from.node_), next_node_(from.next_node_), prev_node_(from.prev_node_),
78 parent_(from.parent_), left_child_(from.left_child_), right_child_(from.right_child_),
80 GUM_CONS_CPY(BinSearchTreeIterator);
82 if (tree_ !=
nullptr) {
83 next_iter_ = tree_->iterator_list_;
84 tree_->iterator_list_ =
this;
85 }
else next_iter_ =
nullptr;
88 template <
typename Val,
class Cmp,
class Node >
89 void BinSearchTreeIterator< Val, Cmp, Node >::initialize_(
90 const BinSearchTree< Val, Cmp, Node >* tree,
91 const Node* current_node,
92 bool add_to_iterator_list) {
96 tree_ =
const_cast< BinSearchTree< Val, Cmp, Node >*
>(tree);
97 node_ =
const_cast< Node*
>(current_node);
99 if (add_to_iterator_list && (tree_ !=
nullptr)) {
100 next_iter_ = tree_->iterator_list_;
101 tree_->iterator_list_ =
this;
105 template <
typename Val,
class Cmp,
class Node >
106 void BinSearchTreeIterator< Val, Cmp, Node >::detachFromTree_() {
107 if (tree_ !=
nullptr) {
108 BinSearchTreeIterator< Val, Cmp, Node >*iter, *prev_iter =
nullptr;
110 for (iter = tree_->iterator_list_; iter !=
this && iter !=
nullptr;
111 prev_iter = iter, iter = iter->next_iter_) {}
113 if (iter !=
nullptr) {
114 if (prev_iter !=
nullptr) prev_iter->next_iter_ = next_iter_;
115 else tree_->iterator_list_ = next_iter_;
120 template <
typename Val,
class Cmp,
class Node >
121 BinSearchTreeIterator< Val, Cmp, Node >::~BinSearchTreeIterator() {
122 GUM_DESTRUCTOR(BinSearchTreeIterator);
128 template <
typename Val,
class Cmp,
class Node >
129 void BinSearchTreeIterator< Val, Cmp, Node >::clear() {
135 next_node_ =
nullptr;
136 prev_node_ =
nullptr;
138 left_child_ =
nullptr;
139 right_child_ =
nullptr;
141 next_iter_ =
nullptr;
144 template <
typename Val,
class Cmp,
class Node >
149 GUM_OP_CPY(BinSearchTreeIterator);
153 if (from.tree_ != tree_) {
157 if (tree_ !=
nullptr) {
158 next_iter_ = tree_->iterator_list_;
159 tree_->iterator_list_ =
this;
160 }
else next_iter_ =
nullptr;
165 next_node_ = from.next_node_;
166 prev_node_ = from.prev_node_;
167 parent_ = from.parent_;
168 left_child_ = from.left_child_;
169 right_child_ = from.right_child_;
175 template <
typename Val,
class Cmp,
class Node >
176 const Val& BinSearchTreeIterator< Val, Cmp, Node >::operator*()
const {
177 if (node_ !=
nullptr)
return node_->value();
179 GUM_ERROR(UndefinedIteratorValue,
"the iterator does not point to a node of the binary tree")
182 template <
typename Val,
class Cmp,
class Node >
183 Node* BinSearchTree< Val, Cmp, Node >::minNode_(Node* node)
const {
184 Node* prevNode =
nullptr;
186 for (; node !=
nullptr; prevNode = node, node = node->leftChild()) {}
191 template <
typename Val,
class Cmp,
class Node >
192 Node* BinSearchTree< Val, Cmp, Node >::maxNode_(Node* node)
const {
193 Node* prevNode =
nullptr;
195 for (; node !=
nullptr; prevNode = node, node = node->rightChild()) {}
200 template <
typename Val,
class Cmp,
class Node >
201 Node* BinSearchTree< Val, Cmp, Node >::succNode_(Node* node)
const {
202 if (node ==
nullptr)
return nullptr;
204 if (node->rightChild())
return minNode_(node->rightChild());
206 Node* par = node->parent();
208 while ((par !=
nullptr) && (node->parentDir() == BinTreeDir::RIGHT_CHILD)) {
216 template <
typename Val,
class Cmp,
class Node >
217 Node* BinSearchTree< Val, Cmp, Node >::prevNode_(Node* node)
const {
218 if (node ==
nullptr)
return nullptr;
220 if (node->leftChild())
return maxNode_(node->leftChild());
222 Node* par = node->parent();
224 while ((par !=
nullptr) && (node->parentDir() == BinTreeDir::LEFT_CHILD)) {
232 template <
typename Val,
class Cmp,
class Node >
237 node_ = node_ !=
nullptr ? tree_->succNode_(node_) : next_node_;
239 if (node_ ==
nullptr) {
240 next_node_ =
nullptr;
241 prev_node_ =
nullptr;
243 left_child_ =
nullptr;
244 right_child_ =
nullptr;
250 template <
typename Val,
class Cmp,
class Node >
256 node_ = node_ !=
nullptr ? tree_->prevNode_(node_) : prev_node_;
258 if (node_ ==
nullptr) {
259 next_node_ =
nullptr;
260 prev_node_ =
nullptr;
262 left_child_ =
nullptr;
263 right_child_ =
nullptr;
269 template <
typename Val,
class Cmp,
class Node >
270 bool BinSearchTreeIterator< Val, Cmp, Node >::operator==(
272 if (node_ !=
nullptr)
return (node_ == from.node_);
274 return ((node_ == from.node_) && (tree_ == from.tree_) && (next_node_ == from.next_node_)
275 && (prev_node_ == from.prev_node_) && (parent_ == from.parent_)
276 && (left_child_ == from.left_child_) && (right_child_ == from.right_child_));
279 template <
typename Val,
class Cmp,
class Node >
280 bool BinSearchTreeIterator< Val, Cmp, Node >::operator!=(
282 if (node_ !=
nullptr)
return (node_ != from.node_);
284 return ((node_ != from.node_) || (tree_ != from.tree_) || (next_node_ != from.next_node_)
285 || (prev_node_ != from.prev_node_) || (parent_ != from.parent_)
286 || (left_child_ != from.left_child_) || (right_child_ != from.right_child_));
289 template <
typename Val,
class Cmp,
class Node >
294 node_ = node_ !=
nullptr ? node_->parent() : parent_;
296 if (node_ ==
nullptr) {
297 next_node_ =
nullptr;
298 prev_node_ =
nullptr;
300 left_child_ =
nullptr;
301 right_child_ =
nullptr;
307 template <
typename Val,
class Cmp,
class Node >
312 node_ = node_ !=
nullptr ? node_->leftChild() : left_child_;
314 if (node_ ==
nullptr) {
315 next_node_ =
nullptr;
316 prev_node_ =
nullptr;
318 left_child_ =
nullptr;
319 right_child_ =
nullptr;
325 template <
typename Val,
class Cmp,
class Node >
330 node_ = node_ !=
nullptr ? node_->rightChild() : right_child_;
332 if (node_ ==
nullptr) {
333 next_node_ =
nullptr;
334 prev_node_ =
nullptr;
336 left_child_ =
nullptr;
337 right_child_ =
nullptr;
349 template <
typename Val,
class Cmp,
class Node >
350 BinSearchTree< Val, Cmp, Node >::BinSearchTree(
bool uniqueness_policy) :
351 root_(nullptr), iterator_list_(nullptr), uniqueness_policy_(uniqueness_policy),
353 GUM_CONSTRUCTOR(BinSearchTree);
354 iter_end_.initialize_(
this,
nullptr,
false);
357 template <
typename Val,
class Cmp,
class Node >
358 BinSearchTree< Val, Cmp, Node >::BinSearchTree(
const BinSearchTree< Val, Cmp, Node >& from) :
359 root_(nullptr), iterator_list_(nullptr), uniqueness_policy_(from.uniqueness_policy_) {
361 GUM_CONS_CPY(BinSearchTree);
364 root_ = copy_(from.root_);
365 nb_elements_ = from.nb_elements_;
368 iter_end_.initialize_(
this,
nullptr,
false);
371 template <
typename Val,
class Cmp,
class Node >
372 void BinSearchTree< Val, Cmp, Node >::clear() {
374 for (iterator *iter = iterator_list_, *next_iter =
nullptr; iter; iter = next_iter) {
375 next_iter = iter->next_iter_;
380 deleteSubTree_(root_);
388 template <
typename Val,
class Cmp,
class Node >
389 BinSearchTree< Val, Cmp, Node >&
390 BinSearchTree< Val, Cmp, Node >::operator=(
const BinSearchTree< Val, Cmp, Node >& from) {
394 GUM_OP_CPY(BinSearchTree);
400 uniqueness_policy_ = from.uniqueness_policy_;
401 root_ = copy_(from.root_);
403 nb_elements_ = from.nb_elements_;
413 template <
typename Val,
class Cmp,
class Node >
414 BinSearchTree< Val, Cmp, Node >::~BinSearchTree() {
416 GUM_DESTRUCTOR(BinSearchTree);
422 template <
typename Val,
class Cmp,
class Node >
423 Node* BinSearchTree< Val, Cmp, Node >::copy_(Node* node, Node* parent, BinTreeDir dir) {
425 if (!node)
return nullptr;
428 Node* new_node =
new Node(*node);
430 if (parent) parent->insertChild(*new_node, dir);
433 copy_(node->leftChild(), new_node, BinTreeDir::LEFT_CHILD);
434 copy_(node->rightChild(), new_node, BinTreeDir::RIGHT_CHILD);
439 template <
typename Val,
class Cmp,
class Node >
440 void BinSearchTree< Val, Cmp, Node >::deleteSubTree_(Node* node) {
445 deleteSubTree_(node->leftChild());
446 deleteSubTree_(node->rightChild());
452 template <
typename Val,
class Cmp,
class Node >
453 Node* BinSearchTree< Val, Cmp, Node >::insert_(
const Val& val) {
460 if (cmp_(val, node->value()))
461 if (!node->leftChild()) {
464 return node->insertLeftChild(val);
466 node = node->leftChild();
468 else if (cmp_(node->value(), val) || !uniqueness_policy_)
469 if (!node->rightChild()) {
472 return node->insertRightChild(val);
474 node = node->rightChild();
485 root_ =
new Node(val);
490 template <
typename Val,
class Cmp,
class Node >
491 const Val& BinSearchTree< Val, Cmp, Node >::insert(
const Val& val) {
492 return insert_(val)->value();
495 template <
typename Val,
class Cmp,
class Node >
496 const Val& BinSearchTree< Val, Cmp, Node >::rootValue()
const {
497 if (root_ ==
nullptr) {
GUM_ERROR(
NotFound,
"no value in an empty Binary Search tree") }
499 return root_->value();
502 template <
typename Val,
class Cmp,
class Node >
503 const Val& BinSearchTree< Val, Cmp, Node >::minValue()
const {
504 if (root_ ==
nullptr) {
GUM_ERROR(
NotFound,
"no minimal value in an empty Binary Search tree") }
506 return minNode_(root_)->value();
509 template <
typename Val,
class Cmp,
class Node >
510 const Val& BinSearchTree< Val, Cmp, Node >::maxValue()
const {
511 if (root_ ==
nullptr) {
GUM_ERROR(
NotFound,
"no maximal value in an empty Binary Search tree") }
513 return maxNode_(root_)->value();
516 template <
typename Val,
class Cmp,
class Node >
517 Node* BinSearchTree< Val, Cmp, Node >::getNode_(
const Val& val)
const {
524 if (cmp_(val, node->value())) {
525 if (!node->leftChild())
return nullptr;
526 else node = node->leftChild();
527 }
else if (cmp_(node->value(), val)) {
528 if (!node->rightChild())
return nullptr;
529 else node = node->rightChild();
537 template <
typename Val,
class Cmp,
class Node >
538 bool BinSearchTree< Val, Cmp, Node >::contains(
const Val& val)
const {
539 return (getNode_(val) !=
nullptr);
542 template <
typename Val,
class Cmp,
class Node >
543 Size BinSearchTree< Val, Cmp, Node >::size()
const {
547 template <
typename Val,
class Cmp,
class Node >
548 bool BinSearchTree< Val, Cmp, Node >::empty()
const {
549 return (nb_elements_ == 0);
552 template <
typename Val,
class Cmp,
class Node >
553 std::string BinSearchTree< Val, Cmp, Node >::toString()
const {
555 std::stringstream stream;
558 for (const_iterator iter = begin(); iter != end(); ++iter, deja =
true) {
559 if (deja) stream <<
" , ";
569 template <
typename Val,
class Cmp,
class Node >
570 bool BinSearchTree< Val, Cmp, Node >::uniquenessPolicy()
const {
571 return uniqueness_policy_;
574 template <
typename Val,
class Cmp,
class Node >
575 void BinSearchTree< Val, Cmp, Node >::setUniquenessPolicy(
const bool new_policy) {
576 uniqueness_policy_ = new_policy;
579 template <
typename Val,
class Cmp,
class Node >
582 iter.initialize_(
this, minNode_(root_),
true);
586 template <
typename Val,
class Cmp,
class Node >
589 iter.initialize_(
this, minNode_(root_),
true);
593 template <
typename Val,
class Cmp,
class Node >
596 iter.initialize_(
this, maxNode_(root_),
true);
600 template <
typename Val,
class Cmp,
class Node >
603 iter.initialize_(
this, maxNode_(root_),
true);
607 template <
typename Val,
class Cmp,
class Node >
612 template <
typename Val,
class Cmp,
class Node >
617 template <
typename Val,
class Cmp,
class Node >
622 template <
typename Val,
class Cmp,
class Node >
627 template <
typename Val,
class Cmp,
class Node >
630 iter.initialize_(
this, root_,
true);
634 template <
typename Val,
class Cmp,
class Node >
637 iter.initialize_(
this, root_,
true);
641 template <
typename Val,
class Cmp,
class Node >
642 void BinSearchTree< Val, Cmp, Node >::erase_(Node* node) {
647 _updateEraseIterators_(node);
655 if (!node->leftChild() && !node->rightChild()) {
657 if (!node->parent()) root_ =
nullptr;
664 else if (!node->leftChild()) {
666 if (!node->parent()) {
670 root_ = node->rightChild();
672 Node * parent = node->parent(), *child = node->rightChild();
673 BinTreeDir dir = node->parentDir();
674 parent->eraseLink(dir);
675 node->eraseRightLink();
676 parent->insertChild(*child, dir);
680 else if (!node->rightChild()) {
682 if (!node->parent()) {
686 root_ = node->leftChild();
688 Node * parent = node->parent(), *child = node->leftChild();
689 BinTreeDir dir = node->parentDir();
690 parent->eraseLink(dir);
691 node->eraseLeftLink();
692 parent->insertChild(*child, dir);
697 _eraseWithTwoChildren_(node);
704 template <
typename Val,
class Cmp,
class Node >
705 void BinSearchTree< Val, Cmp, Node >::_eraseWithTwoChildren_(Node* node) {
720 Node* successor = succNode_(node);
722 if (successor == node->rightChild()) {
723 Node* left_child = node->leftChild();
724 node->eraseLeftLink();
725 node->eraseRightLink();
726 successor->insertLeftChild(*left_child);
728 if (!node->parent()) {
734 BinTreeDir par_dir = node->parentDir();
735 Node* parent = node->parent();
736 parent->eraseLink(par_dir);
737 parent->insertChild(*successor, par_dir);
740 Node* parent = successor->parent();
741 parent->eraseLeftLink();
743 if (successor->rightChild()) {
744 Node* succ_child = successor->rightChild();
745 successor->eraseRightLink();
746 parent->insertLeftChild(*succ_child);
749 Node *left = node->leftChild(), *right = node->rightChild();
750 node->eraseLeftLink();
751 node->eraseRightLink();
752 successor->insertLeftChild(*left);
753 successor->insertRightChild(*right);
755 if (!node->parent()) {
759 BinTreeDir par_dir = node->parentDir();
760 Node* parent = node->parent();
761 parent->eraseLink(par_dir);
762 parent->insertChild(*successor, par_dir);
767 template <
typename Val,
class Cmp,
class Node >
768 void BinSearchTree< Val, Cmp, Node >::erase(
const Val& val) {
769 Node* n = getNode_(val);
771 if (n ==
nullptr)
GUM_ERROR(gum::NotFound,
"Value \"" << val <<
"\" not found")
776 template < typename Val, class
Cmp, class Node >
777 void BinSearchTree< Val,
Cmp, Node >::erase(const iterator& iter) {
781 template <
typename Val,
class Cmp,
class Node >
782 void BinSearchTree< Val, Cmp, Node >::_updateEraseIterators_(Node* node) {
783 for (iterator* iter = iterator_list_; iter; iter = iter->next_iter_) {
786 if (iter->node_ == node) {
787 iter->node_ =
nullptr;
788 iter->next_node_ = succNode_(node);
789 iter->prev_node_ = prevNode_(node);
790 iter->parent_ = node->parent();
791 iter->left_child_ = node->leftChild();
792 iter->right_child_ = node->rightChild();
793 }
else if (!iter->node_) {
794 if (iter->next_node_ == node) iter->next_node_ = succNode_(node);
796 if (iter->prev_node_ == node) iter->prev_node_ = prevNode_(node);
798 if (iter->parent_ == node) iter->parent_ = node->parent();
800 if (iter->left_child_ == node) iter->left_child_ = node->leftChild();
802 if (iter->right_child_ == node) iter->right_child_ = node->rightChild();
Basic binary search trees.
BinSearchTreeIterator()
Class Constructors and Destructors.
Exception : a similar element already exists.
Exception : the element we looked for cannot be found.
#define GUM_ERROR(type, msg)
gum is the global namespace for all aGrUM entities