lasd/librerie/exercise4/binarytree/binarytree.hpp

251 lines
9.8 KiB
C++
Raw Normal View History

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