diff --git a/librerie/exercise3/binarytree/lnk/binarytreelnk.cpp b/librerie/exercise3/binarytree/lnk/binarytreelnk.cpp index d374ceb..1321605 100644 --- a/librerie/exercise3/binarytree/lnk/binarytreelnk.cpp +++ b/librerie/exercise3/binarytree/lnk/binarytreelnk.cpp @@ -2,9 +2,158 @@ namespace lasd { /* ************************************************************************** */ +template +struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::NodeLnk::operator=(const NodeLnk& node){ + data = node.data; + left = node.left; + right = node.right; + return *this; +} -// ... +template +struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::NodeLnk::operator=(NodeLnk&& node) noexcept{ + std::swap(data, node.data); + std::swap(left, node.left); + std::swap(right, node.right); + return *this; +} -/* ************************************************************************** */ +template +bool BinaryTreeLnk::NodeLnk::IsLeaf() const noexcept{ + return (left==nullptr && right==nullptr); +} + +template +bool BinaryTreeLnk::NodeLnk::HasLeftChild() const noexcept{ + return (left!=nullptr); +} + +template +bool BinaryTreeLnk::NodeLnk::HasRightChild() const noexcept{ + return (right!=nullptr); +} + +template +NodeLnk& BinaryTreeLnk::NodeLnk::LeftChild() const{ + return *left; +} + +template +NodeLnk& BinaryTreeLnk::NodeLnk::RightChild() const{ + return *right; +} + +template +BinaryTreeLnk::BinaryTreeLnk(){ + size = 0; +} + +// creates a tree from a linear container in breadth +template +BinaryTreeLnk::BinaryTreeLnk(const LinearContainer& lc){ + root = CreateTreeFromLinearContainerInBreadth(lc,0); + size = lc.Size(); +} + +struct BinaryTreeLnk::NodeLnk* CreateTreeFromLinearContainerInBreadth(const LinearContainer& lc, ulong position){ + if(position >= lc.Size()) return nullptr; + + struct BinaryTreeLnk::NodeLnk* tmp = CreateNode(lc[position]); + // if(position == 0) root = tmp; + + tmp->left = CreateTreeFromLinearContainerInBreadth(lc, (2*position)+1); + tmp->right = CreateTreeFromLinearContainerInBreadth(lc, (2*position)+2); + + return tmp; + +} + +template +struct BinaryTreeLnk::NodeLnk* CreateNode(const Data& data){ + struct BinaryTreeLnk::NodeLnk* newNode = new struct BinaryTreeLnk::NodeLnk(); + newNode->data = data; + newNode->left = nullptr; + newNode->right = nullptr; + return newNode; +} + +template +BinaryTreeLnk::BinaryTreeLnk(const BinaryTreeLnk& tree){ + if(tree.root == nullptr) return; + size = tree.size; + root = CopyTree(&tree.Root()); +} + +BinaryTreeLnk::NodeLnk* BinaryTreeLnk::CopyTree(struct BinaryTreeLnk::NodeLnk* nodeToCopy){ + struct BinaryTreeLnk::NodeLnk* tmp = CreateNode(nodeToCopy.Element()); + + if(nodeToCopy.HasLeftChild()) + tmp->left = copyTrees(&(nodeToCopy.LeftChild())); + else + tmp->left = nullptr; + + if(nodeToCopy.HasRightChild()) + tmp->right = copyTrees(&(nodeToCopy.RightChild())); + else + tmp->right = nullptr; + + return tmp; +} + +template +BinaryTreeLnk::BinaryTreeLnk(BinaryTreeLnk&& tree) noexcept{ + std::swap(size, tree.size); + std::swap(root, tree.root); +} + +template +BinaryTreeLnk::~BinaryTreeLnk(){ + Clear(); +} + +template +void BinaryTreeLnk::DeleteTree(BinaryTreeLnk::NodeLnk* node){ + if(node == nullptr) return; + DeleteTree(node->left); + DeleteTree(node->right); + delete node; +} + +template +BinaryTreeLnk& BinaryTreeLnk::operator=(const BinaryTreeLnk& tree){ + Clear(); + size = tree.size; + if(tree.root != nullptr) + root = CopyTree(&tree.Root()); + return *this; + +} + +template +BinaryTreeLnk& BinaryTreeLnk::operator=(BinaryTreeLnk&& tree) noexcept{ + std::swap(size, tree.size); + std::swap(root, tree.root); + return *this; +} + +template +bool BinaryTreeLnk::operator==(const BinaryTreeLnk& tree) const noexcept{ + return (Root() == tree.Root()); +} + +template +bool BinaryTreeLnk::operator!=(const BinaryTreeLnk& tree) const noexcept{ + return !(*this == tree); +} + +template +struct NodeLnk& Root() override{ + return *root; +} + +template +void Clear() override{ + DeleteTree(root); +} } diff --git a/librerie/exercise3/binarytree/lnk/binarytreelnk.hpp b/librerie/exercise3/binarytree/lnk/binarytreelnk.hpp index 40bba30..3f15ed8 100644 --- a/librerie/exercise3/binarytree/lnk/binarytreelnk.hpp +++ b/librerie/exercise3/binarytree/lnk/binarytreelnk.hpp @@ -20,7 +20,9 @@ private: protected: using BinaryTree::size; + struct NodeLnk* root = nullptr; + // Node struct NodeLnk : virtual protected BinaryTree::Node { // Must extend Node private: @@ -32,11 +34,10 @@ protected: struct* NodeLnk* right; public: - - NodeLnk& operator=(const Node&); // Copy assignment of abstract types should not be possible. + NodeLnk& operator=(const NodeLnk&); // Copy assignment of abstract types should not be possible. // Move assignment - NodeLnk& operator=(Node&&) noexcept override; // Move assignment of abstract types should not be possible. + Node& operator=(Node&&) noexcept override; // Move assignment of abstract types should not be possible. bool IsLeaf() const noexcept override; // (concrete function should not throw exceptions) bool HasLeftChild() const noexcept override; // (concrete function should not throw exceptions) bool HasRightChild() const noexcept override; // (concrete function should not throw exceptions) @@ -44,6 +45,8 @@ protected: Node& LeftChild() const override; // (concrete function must throw std::out_of_range when not existent) Node& RightChild() const override; // (concrete function must throw std::out_of_range when not existent) + struct BinaryTreeLnk::NodeLnk* CreateNode(const Data& data); + }; public: @@ -54,47 +57,50 @@ public: /* ************************************************************************ */ // Specific constructors - BinaryTreeLnk(argument) specifiers; // A binary tree obtained from a LinearContainer + BinaryTreeLnk(const LinearContainer&); // A binary tree obtained from a LinearContainer /* ************************************************************************ */ // Copy constructor - // BinaryTreeLnk(argument) specifiers; + BinaryTreeLnk(const BinaryTreeLnk&); // Move constructor - // BinaryTreeLnk(argument) specifiers; + BinaryTreeLnk(BinaryTreeLnk&&) noexcept; /* ************************************************************************ */ // Destructor - // ~BinaryTreeLnk() specifiers; + virtual ~BinaryTreeLnk(); /* ************************************************************************ */ // Copy assignment - // type operator=(argument) specifiers; + BinaryTreeLnk& operator=(const BinaryTreeLnk&); // Move assignment - // type operator=(argument) specifiers; + BinaryTreeLnk operator=(BinaryTreeLnk&&) noexcept; /* ************************************************************************ */ // Comparison operators - // type operator==(argument) specifiers; - // type operator!=(argument) specifiers; + bool operator==(const BinaryTreeLnk&) const noexcept; + bool operator!=(const BinaryTreeLnk&) const noexcept; /* ************************************************************************ */ // Specific member functions (inherited from BinaryTree) - // type Root() specifiers; // Override BinaryTree member (throw std::length_error when empty) + struct NodeLnk& Root() override; // Override BinaryTree member (throw std::length_error when empty) /* ************************************************************************ */ // Specific member functions (inherited from Container) - // type Clear() specifiers; // Override Container member + void Clear() override; // Override Container member + struct BinaryTreeLnk::NodeLnk* CreateTreeFromLinearContainerInBreadth(const LinearContainer&,ulong); + struct BinaryTreeLnk::NodeLnk* CopyTree(struct BinaryTreeLnk::NodeLnk*); + void DeleteTree(BinaryTreeLnk::NodeLnk* node) }; /* ************************************************************************** */