2021-05-11 06:51:06 +02:00
# ifndef BINARYTREE_HPP
# define BINARYTREE_HPP
# include "../container/container.hpp"
# include "../iterator/iterator.hpp"
2021-05-11 06:52:44 +02:00
# include "../queue/queue.hpp"
# include "../queue/vec/queuevec.hpp"
# include "../queue/lst/queuelst.hpp"
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
# include "../stack/stack.hpp"
# include "../stack/lst/stacklst.hpp"
# include "../stack/vec/stackvec.hpp"
2021-05-11 06:51:06 +02:00
namespace lasd {
template < typename Data >
2021-05-11 06:52:44 +02:00
class BinaryTree : virtual public InOrderMappableContainer < Data > ,
virtual public BreadthMappableContainer < Data > ,
virtual public InOrderFoldableContainer < Data > ,
virtual public BreadthFoldableContainer < Data > { // Must extend InOrder/BreadthMappableContainer<Data> and InOrder/BreadthFoldableContainer<Data>
2021-05-11 06:51:06 +02:00
public :
struct Node {
private :
protected :
2021-05-11 06:52:44 +02:00
Data data ;
// Comparison operators
bool operator = = ( const Node & ) const noexcept ; // Comparison of abstract types is possible, but should not be visible.
bool operator ! = ( const Node & ) const noexcept ; // Comparison of abstract types is possible, but should not be visible.
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool EqualNodes ( const Node & , const Node & ) const ;
2021-05-11 06:51:06 +02:00
public :
2021-05-11 06:52:44 +02:00
friend class BinaryTree < Data > ;
2021-05-11 06:51:06 +02:00
// Destructor
2021-05-11 06:52:44 +02:00
virtual ~ Node ( ) = default ;
2021-05-11 06:51:06 +02:00
// Copy assignment
2021-05-11 06:52:44 +02:00
Node & operator = ( const Node & ) = delete ; // Copy assignment of abstract types should not be possible.
2021-05-11 06:51:06 +02:00
// Move assignment
2021-05-11 06:52:44 +02:00
Node & operator = ( Node & & ) noexcept = delete ; // Move assignment of abstract types should not be possible.
2021-05-11 06:51:06 +02:00
// Specific member functions
2021-05-11 06:52:44 +02:00
Data & Element ( ) ; // Mutable access to the element (concrete function should not throw exceptions)
const Data & Element ( ) const ; // Immutable access to the element (concrete function should not throw exceptions)
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual bool IsLeaf ( ) const noexcept = 0 ; // (concrete function should not throw exceptions)
virtual bool HasLeftChild ( ) const noexcept = 0 ; // (concrete function should not throw exceptions)
virtual bool HasRightChild ( ) const noexcept = 0 ; // (concrete function should not throw exceptions)
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual Node & LeftChild ( ) const = 0 ; // (concrete function must throw std::out_of_range when not existent)
virtual Node & RightChild ( ) const = 0 ; // (concrete function must throw std::out_of_range when not existent)
2021-05-11 06:51:06 +02:00
} ;
2021-05-11 06:52:44 +02:00
virtual ~ BinaryTree ( ) = default ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BinaryTree & operator = ( const BinaryTree & ) = delete ; // Copy assignment of abstract types should not be possible.
BinaryTree & operator = ( BinaryTree & & ) noexcept = delete ; // Move assignment of abstract types should not be possible.
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool operator = = ( const BinaryTree & ) const noexcept ; // Comparison of abstract binary tree is possible.
bool operator ! = ( const BinaryTree & ) const noexcept ; // Comparison of abstract binary tree is possible.
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual Node & Root ( ) const = 0 ; // (concrete function must throw std::length_error when empty)
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
/* ----- Map and fold functions ----- */
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual void MapPreOrder ( const typename MappableContainer < Data > : : MapFunctor , void * ) override ; // Override MappableContainer member
virtual void MapPostOrder ( const typename MappableContainer < Data > : : MapFunctor , void * ) override ; // Override MappableContainer member
virtual void MapInOrder ( const typename MappableContainer < Data > : : MapFunctor , void * ) override ; // Override InOrderMappableContainer member
virtual void MapBreadth ( const typename MappableContainer < Data > : : MapFunctor , void * ) override ; // Override BreadthMappableContainer member
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual void FoldPreOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * ) const override ; // Override FoldableContainer member
virtual void FoldPostOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * ) const override ; // Override FoldableContainer member
virtual void FoldInOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * ) const override ; // Override InOrderFoldableContainer member
virtual void FoldBreadth ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * ) const override ; // Override BreadthFoldableContainer member
2021-05-11 06:51:06 +02:00
protected :
2021-05-11 06:52:44 +02:00
using BreadthMappableContainer < Data > : : size ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
/* ----- Auxiliary map and fold functions ----- */
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
void MapPreOrder ( const typename MappableContainer < Data > : : MapFunctor , void * , Node * ) ; // Accessory function executing from one node of the tree
void MapPostOrder ( const typename MappableContainer < Data > : : MapFunctor , void * , Node * ) ; // Accessory function executing from one node of the tree
void MapInOrder ( const typename MappableContainer < Data > : : MapFunctor , void * , Node * ) ; // Accessory function executing from one node of the tree
void MapBreadth ( const typename MappableContainer < Data > : : MapFunctor , void * , Node * ) ; // Accessory function executing from one node of the tree
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
void FoldPreOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * , const Node * ) const ; // Accessory function executing from one node of the tree
void FoldPostOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * , const Node * ) const ; // Accessory function executing from one node of the tree
void FoldInOrder ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * , const Node * ) const ; // Accessory function executing from one node of the tree
void FoldBreadth ( const typename FoldableContainer < Data > : : FoldFunctor , const void * , void * , Node * ) const ; // Accessory function executing from one node of the tree
2021-05-11 06:51:06 +02:00
} ;
template < typename Data >
2021-05-11 06:52:44 +02:00
class BTPreOrderIterator : virtual public ForwardIterator < Data > { // Must extend ForwardIterator<Data>
2021-05-11 06:51:06 +02:00
protected :
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * curr = nullptr ;
StackLst < struct BinaryTree < Data > : : Node * > stack ;
2021-05-11 06:51:06 +02:00
public :
2021-05-11 06:52:44 +02:00
virtual ~ BTPreOrderIterator ( ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTPreOrderIterator ( const BinaryTree < Data > & ) ; // An iterator over a given binary tree
BTPreOrderIterator ( const BTPreOrderIterator & ) ;
BTPreOrderIterator ( BTPreOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTPreOrderIterator & operator = ( const BTPreOrderIterator & ) ;
BTPreOrderIterator & operator = ( BTPreOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool operator = = ( const BTPreOrderIterator & ) const noexcept ;
bool operator ! = ( const BTPreOrderIterator & ) const noexcept ;
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from Iterator)
2021-05-11 06:52:44 +02:00
Data & operator * ( ) const ; // (throw std::out_of_range when terminated)
bool Terminated ( ) const noexcept ; // (should not throw exceptions)
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from ForwardIterator)
2021-05-11 06:52:44 +02:00
void operator + + ( ) ; // (throw std::out_of_range when terminated)
2021-05-11 06:51:06 +02:00
} ;
/* ************************************************************************** */
template < typename Data >
2021-05-11 06:52:44 +02:00
class BTPostOrderIterator : virtual public ForwardIterator < Data > { // Must extend ForwardIterator<Data>
2021-05-11 06:51:06 +02:00
protected :
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * curr = nullptr ;
StackLst < struct BinaryTree < Data > : : Node * > stack ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * DeepestLeftLeaf ( struct BinaryTree < Data > : : Node * ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
public :
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTPostOrderIterator ( const BinaryTree < Data > & ) ; // An iterator over a given binary tree
BTPostOrderIterator ( const BTPostOrderIterator & ) ;
BTPostOrderIterator ( BTPostOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual ~ BTPostOrderIterator ( ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTPostOrderIterator & operator = ( const BTPostOrderIterator & ) ;
BTPostOrderIterator & operator = ( BTPostOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool operator = = ( const BTPostOrderIterator & ) const noexcept ;
bool operator ! = ( const BTPostOrderIterator & ) const noexcept ;
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from Iterator)
2021-05-11 06:52:44 +02:00
Data & operator * ( ) const ; // (throw std::out_of_range when terminated)
bool Terminated ( ) const noexcept ; // (should not throw exceptions)
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from ForwardIterator)
2021-05-11 06:52:44 +02:00
void operator + + ( ) ; // (throw std::out_of_range when terminated)
2021-05-11 06:51:06 +02:00
} ;
/* ************************************************************************** */
template < typename Data >
2021-05-11 06:52:44 +02:00
class BTInOrderIterator : virtual public ForwardIterator < Data > { // Must extend ForwardIterator<Data>
2021-05-11 06:51:06 +02:00
protected :
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * curr = nullptr ;
StackLst < struct BinaryTree < Data > : : Node * > stack ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * MostLeftNode ( struct BinaryTree < Data > : : Node & ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
public :
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTInOrderIterator ( const BinaryTree < Data > & ) ; // An iterator over a given binary tree
BTInOrderIterator ( const BTInOrderIterator & ) ;
BTInOrderIterator ( BTInOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual ~ BTInOrderIterator ( ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTInOrderIterator & operator = ( const BTInOrderIterator & ) ;
BTInOrderIterator & operator = ( BTInOrderIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool operator = = ( const BTInOrderIterator & ) const noexcept ;
bool operator ! = ( const BTInOrderIterator & ) const noexcept ;
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from Iterator)
2021-05-11 06:52:44 +02:00
Data & operator * ( ) const ; // (throw std::out_of_range when terminated)
bool Terminated ( ) const noexcept ; // (should not throw exceptions)
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from ForwardIterator)
2021-05-11 06:52:44 +02:00
void operator + + ( ) ; // (throw std::out_of_range when terminated)
2021-05-11 06:51:06 +02:00
} ;
template < typename Data >
2021-05-11 06:52:44 +02:00
class BTBreadthIterator : virtual public ForwardIterator < Data > { // Must extend ForwardIterator<Data>
2021-05-11 06:51:06 +02:00
protected :
2021-05-11 06:52:44 +02:00
struct BinaryTree < Data > : : Node * curr = nullptr ;
QueueVec < struct BinaryTree < Data > : : Node * > queue ;
2021-05-11 06:51:06 +02:00
public :
2021-05-11 06:52:44 +02:00
BTBreadthIterator ( const BinaryTree < Data > & ) ; // An iterator over a given binary tree
BTBreadthIterator ( const BTBreadthIterator & ) ;
BTBreadthIterator ( BTBreadthIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
virtual ~ BTBreadthIterator ( ) ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
BTBreadthIterator & operator = ( const BTBreadthIterator & ) ;
BTBreadthIterator & operator = ( BTBreadthIterator & & ) noexcept ;
2021-05-11 06:51:06 +02:00
2021-05-11 06:52:44 +02:00
bool operator = = ( const BTBreadthIterator & ) const noexcept ;
bool operator ! = ( const BTBreadthIterator & ) const noexcept ;
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from Iterator)
2021-05-11 06:52:44 +02:00
Data & operator * ( ) const ; // (throw std::out_of_range when terminated)
bool Terminated ( ) const noexcept ; // (should not throw exceptions)
2021-05-11 06:51:06 +02:00
// Specific member functions (inherited from ForwardIterator)
2021-05-11 06:52:44 +02:00
void operator + + ( ) ; // (throw std::out_of_range when terminated)
2021-05-11 06:51:06 +02:00
} ;
}
# include "binarytree.cpp"
# endif