namespace lasd { /* ----- begin of struct NodeLnk ----- */ template struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::NodeLnk::operator=(const BinaryTreeLnk::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 struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::NodeLnk::LeftChild() const{ return *left; } template struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::NodeLnk::RightChild() const{ return *right; } /* ----- end of struct NodeLnk ----- */ /* ----- begin of class BinaryTreeLnk ----- */ // creates a tree from a linear container in breadth template BinaryTreeLnk::BinaryTreeLnk(const LinearContainer& lc){ root = CreateTreeFromLinearContainerInBreadth(lc,0); size = lc.Size(); } template struct BinaryTreeLnk::NodeLnk* BinaryTreeLnk::CreateTreeFromLinearContainerInBreadth(const LinearContainer& lc, ulong position){ if(position >= lc.Size()) return nullptr; struct BinaryTreeLnk::NodeLnk* tmp = CreateNode(lc[position]); tmp->left = CreateTreeFromLinearContainerInBreadth(lc, (2*position)+1); tmp->right = CreateTreeFromLinearContainerInBreadth(lc, (2*position)+2); return tmp; } template struct BinaryTreeLnk::NodeLnk* BinaryTreeLnk::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()); } template struct BinaryTreeLnk::NodeLnk* BinaryTreeLnk::CopyTree(struct BinaryTreeLnk::Node* nodeToCopy){ if(nodeToCopy==nullptr) return nullptr; struct BinaryTreeLnk::NodeLnk* tmp = CreateNode(nodeToCopy->Element()); if(nodeToCopy->HasLeftChild()) tmp->left = CopyTree(&(nodeToCopy->LeftChild())); else tmp->left = nullptr; if(nodeToCopy->HasRightChild()) tmp->right = CopyTree(&(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; } /* ** operator== and operator!= can be removed from BinaryTreeLnk since they are ** inherited from BinaryTree. They're here just for clarity and because they're ** in the template. ** Maybe you can make them more optimized here. */ template bool BinaryTreeLnk::operator==(const BinaryTreeLnk& tree) const noexcept{ return (BinaryTree::operator==(tree)); } template bool BinaryTreeLnk::operator!=(const BinaryTreeLnk& tree) const noexcept{ return !(*this == tree); } template struct BinaryTreeLnk::NodeLnk& BinaryTreeLnk::Root() const{ if(size==0) throw std::length_error("Empty tree!"); return *root; } template void BinaryTreeLnk::Clear(){ DeleteTree(root); root = nullptr; size = 0; } }