namespace lasd { template BST::BST(const LinearContainer& lc){ for(ulong i=0 ; i BST::BST(const BST& bst) : BinaryTreeLnk(bst){} template BST::BST(BST&& bst) noexcept : BinaryTreeLnk(std::move(bst)){} template BST::~BST(){ BinaryTreeLnk::Clear(); } template BST& BST::operator=(const BST& bst){ BinaryTreeLnk::operator=(bst); return *this; } template BST& BST::operator=(BST&& bst) noexcept{ BinaryTreeLnk::operator=(std::move(bst)); return *this; } template bool BST::operator==(const BST& bst) const noexcept{ if(size != bst.Size()) return false; BTInOrderIterator itr1(*this); BTInOrderIterator itr2(bst); for(; !itr1.Terminated() ; ++itr1, ++itr2){ if(*itr1 != *itr2) return false; } return true; } template bool BST::operator!=(const BST& bst) const noexcept{ return !(*this == bst); } template void BST::Insert(const Data& data) noexcept{ NodeLnk*& pointer = FindPointerTo(root, data); if(pointer == nullptr){ pointer = BinaryTreeLnk::CreateNode(data); size++; } } template void BST::Insert(Data&& data) noexcept{ NodeLnk*& pointer = FindPointerTo(root, data); if(pointer == nullptr){ pointer = new NodeLnk(); std::swap(pointer->value, data); size++; } } template void BST::Remove(const Data& data) noexcept{ delete Detach(FindPointerTo(root,data)); } template const Data& BST::Min() const{ if(root == nullptr) throw std::length_error("Empty tree!"); return FindPointerToMin(root)->Element(); } template Data BST::MinNRemove(){ if(root == nullptr) throw std::length_error("Empty tree!"); return DataNDelete(DetachMin(root)); } template void BST::RemoveMin(){ if(root == nullptr) throw std::length_error("Empty tree!"); delete DetachMin(root); } template const Data& BST::Max() const{ if(root == nullptr) throw std::length_error("Empty tree!"); return FindPointerToMax(root)->Element(); } template Data BST::MaxNRemove(){ if(root == nullptr) throw std::length_error("Empty tree!"); return DataNDelete(DetachMax(root)); } template void BST::RemoveMax(){ if(root == nullptr) throw std::length_error("Empty tree!"); delete DetachMax(root); } template const Data& BST::Predecessor(const Data& data) const{ NodeLnk* const* ptr = FindPointerToPredecessor(root, data); if(ptr!=nullptr){ return (*(*ptr)).Element(); }else{ throw std::length_error("Predecessor not found!"); } } template Data BST::PredecessorNRemove(const Data& data){ NodeLnk** ptr = FindPointerToPredecessor(root,data); if(ptr!=nullptr){ return DataNDelete(Detach(*ptr)); }else{ throw std::length_error("Predecessor not found!"); } } template void BST::RemovePredecessor(const Data& data){ NodeLnk** ptr = FindPointerToPredecessor(root,data); if(ptr!=nullptr){ delete Detach(*ptr); }else{ throw std::length_error("Predecessor not found!"); } } template const Data& BST::Successor(const Data& data) const{ NodeLnk* const* ptr = FindPointerToSuccessor(root, data); if(ptr!=nullptr){ return (*(*ptr)).Element(); }else{ throw std::length_error("Successor not found!"); } } template Data BST::SuccessorNRemove(const Data& data){ NodeLnk** ptr = FindPointerToSuccessor(root,data); if(ptr!=nullptr){ return DataNDelete(Detach(*ptr)); }else{ throw std::length_error("Successor not found!"); } } template void BST::RemoveSuccessor(const Data& data){ NodeLnk** ptr = FindPointerToSuccessor(root,data); if(ptr!=nullptr){ delete Detach(*ptr); }else{ throw std::length_error("Successor not found!"); } } template bool BST::Exists(const Data& data) const noexcept{ return (FindPointerTo(root, data) != nullptr); } template Data BST::DataNDelete(struct BST::NodeLnk* ptr){ Data data = ptr->Element(); delete ptr; return data; } template typename BST::NodeLnk* BST::Detach(struct BST::NodeLnk*& ptrref) noexcept{ if(ptrref == nullptr) return nullptr; if(ptrref->left == nullptr){ return SkipOnRight(ptrref); } else if(ptrref->right == nullptr){ return SkipOnLeft(ptrref); } else{ NodeLnk* maxNode = DetachMax(ptrref->left); std::swap(ptrref->Element() , maxNode->Element()); return maxNode; } } template typename BST::NodeLnk* BST::DetachMin(struct BST::NodeLnk*& ptrref) noexcept{ return SkipOnRight(FindPointerToMin(ptrref)); } template typename BST::NodeLnk* BST::DetachMax(struct BST::NodeLnk*& ptrref) noexcept{ return SkipOnLeft(FindPointerToMax(ptrref)); } template typename BST::NodeLnk* BST::SkipOnLeft(struct BST::NodeLnk*& ptrref) noexcept{ NodeLnk* left = nullptr; if(ptrref != nullptr){ std::swap(left, ptrref->left); std::swap(left, ptrref); --size; } return left; } template typename BST::NodeLnk* BST::SkipOnRight(struct BST::NodeLnk*& ptrref) noexcept{ NodeLnk* right = nullptr; if(ptrref != nullptr){ std::swap(right, ptrref->right); std::swap(right, ptrref); --size; } return right; } template typename BST::NodeLnk* const& BST::FindPointerToMin(struct BST::NodeLnk* const& node) const noexcept{ NodeLnk* const* ptr = &node; NodeLnk* curr = node; if(curr!=nullptr){ while(curr->left != nullptr){ ptr = &curr->left; curr = curr->left; } } return *ptr; } template typename BST::NodeLnk*& BST::FindPointerToMin(struct BST::NodeLnk*& node) noexcept{ return const_cast(static_cast *>(this)->FindPointerToMin(node)); } template typename BST::NodeLnk* const& BST::FindPointerToMax(struct BST::NodeLnk* const& node) const noexcept{ NodeLnk* const* ptr = &node; NodeLnk* curr = node; if(curr!=nullptr){ while(curr->right != nullptr){ ptr = &curr->right; curr = curr->right; } } return *ptr; } template typename BST::NodeLnk*& BST::FindPointerToMax(struct BST::NodeLnk*& node) noexcept{ return const_cast(static_cast *>(this)->FindPointerToMax(node)); } /* ---- END ----- */ template typename BST::NodeLnk* const& BST::FindPointerTo(struct BST::NodeLnk* const& ref, Data data) const noexcept{ NodeLnk* const* pointer = &ref; NodeLnk* current = ref; if(current != nullptr){ while(current != nullptr && current->Element() != data){ if(current->Element() < data){ pointer = ¤t->right; current = current->right; }else if(current->Element() > data){ pointer = ¤t->left; current = current->left; } } return *pointer; }else{ return *pointer; } } template typename BST::NodeLnk*& BST::FindPointerTo(struct BST::NodeLnk*& node, Data data) noexcept{ return const_cast(static_cast *>(this)->FindPointerTo(node, data)); } template typename BST::NodeLnk* const* BST::FindPointerToPredecessor(struct BST::NodeLnk* const& ref, Data data) const noexcept{ NodeLnk* const* pointer = &ref; NodeLnk* current = ref; NodeLnk* const* lastRight = pointer; if(ref != nullptr){ while( current != nullptr){ if(data == current->Element()){ if(current->HasLeftChild()){ return pointer = &(FindPointerToMax(current->left)); } return lastRight; }else if(data < current->Element()){ pointer = ¤t->left; current = current->left; }else{ lastRight = pointer; pointer = ¤t->right; current = current->right; } } return lastRight; }else{ return lastRight; } } template typename BST::NodeLnk** BST::FindPointerToPredecessor(struct BST::NodeLnk*& node, Data data) noexcept{ return const_cast(static_cast *>(this)->FindPointerToPredecessor(node, data)); } template typename BST::NodeLnk* const* BST::FindPointerToSuccessor(struct BST::NodeLnk* const& ref, Data data) const noexcept{ NodeLnk* const* pointer = &ref; NodeLnk* current = ref; NodeLnk* const* lastLeft = nullptr; if(ref != nullptr){ while( current != nullptr){ if(data == current->Element()){ if(current->HasRightChild()){ return pointer = &(FindPointerToMin(current->right)); } return lastLeft; }else if(data < current->Element()){ lastLeft = pointer; pointer = ¤t->left; current = current->left; }else{ pointer = ¤t->right; current = current->right; } } return lastLeft; }else{ return lastLeft; } } template typename BST::NodeLnk** BST::FindPointerToSuccessor(struct BST::NodeLnk*& node, Data data) noexcept{ return const_cast(static_cast *>(this)->FindPointerToSuccessor(node, data)); } /* ************************************************************************** */ }