#ifndef MTREE_H #define MTREE_H ///////////////////////////////////////////////////////////////// // MTree.h - M-ary Tree data structure // // // // Application: Help for CSE687 Pr#2, Spring 2015 // // Platform: Dell XPS 2720, Win 8.1 Pro, Visual Studio 2013 // // Author: Jim Fawcett, CST 4-187, 443-3948 // // jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////// /* * Package Operations: * ------------------- * This package contains classes MTree and MNode. * MTree is an M-ary tree, e.g., each MNode has zero or more * children. Note that this is not a balanced binary tree. No * order is imposed on the children of any node. They simply appear * in the order they were added. * * M-ary trees are often used to represent parse trees where the * ordering of nodes depends on the structure of the entity being * represented, e.g., source code, XML, or HTML. * * MTree's nodes are members of class MNode. each MNode * holds a vector of std::shared_prt's to it's children, if any. * the value of the template parameter T represents what each node * of the tree holds, e.g., a string representing a grammatical * constructor, or XML or HTML element. * * Required Files: * --------------- * - MTree.h and MTree.cpp * * Build Process: * -------------- * devenv MTree.sln /debug rebuild * * Maintenance History: * -------------------- * This is a complete redesign of an earlier MTree class that uses * C++11 constructs, most noteably std::shared_ptr. * * Ver 1 : 4 Feb 15 * - first release * */ #include #include #include #include #include "../MNode/MNode.h" #include "../Utilities/Utilities.h" ///////////////////////////////////////////////////////////////////////////// // MTree class template class MTree { public: using sPtr = std::shared_ptr < MNode > ; MTree(sPtr& pRoot); MTree(const T& t=T()); MTree(const MTree& tree); MTree(MTree&& tree); ~MTree(); MTree& operator=(const MTree& tree); MTree& operator=(MTree&& tree); sPtr root(); sPtr findById(const std::string& id); std::vector findByValue(const T& value); std::vector children(const T& value, size_t count=1); std::vector descendents(const T& value, size_t count=1); private: void decendentsHelper(sPtr ptr); sPtr pRoot_ = nullptr; std::vector collection_; }; //----< construct tree from root node >-------------------------------------- template MTree::MTree(sPtr& pRoot) : pRoot_(pRoot) {} //----< construct tree from value for new root node >------------------------ template MTree::MTree(const T& t) : pRoot_(sPtr(new MNode(t))) {} //----< destructor >--------------------------------------------------------- template MTree::~MTree() {} //----< copy constructor >--------------------------------------------------- template MTree::MTree(const MTree& tree) { pRoot_ = tree.pRoot_->clone(); } //----< move constructor >--------------------------------------------------- template MTree::MTree(MTree&& tree) { pRoot_ = tree.pRoot_; tree.pRoot_ = nullptr; } //----< copy assignment >---------------------------------------------------- template MTree& MTree::operator=(const MTree& tree) { if (this == &tree) return *this; pRoot_ = tree.pRoot_->clone(); return *this; } //----< move assignment >---------------------------------------------------- template MTree& MTree::operator=(MTree&& tree) { if (this == &tree) return *this; pRoot_ = tree.pRoot_; tree.pRoot_ = nullptr; return *this; } //----< return tree root node >---------------------------------------------- template std::shared_ptr> MTree::root() { return pRoot_; } //----< find tree node by id >----------------------------------------------- template std::shared_ptr> MTree::findById(const std::string& id) { if (pRoot_->id() == id) return pRoot_; return pRoot_->findById(id); } //----< find tree nodes by value >------------------------------------------- template std::vector>> MTree::findByValue(const T& value) { std::vector temp = pRoot_->findByValue(value); if (pRoot_->value() == value) temp.insert(begin(temp), pRoot_); return temp; } //----< find children of node with specified value >------------------------- template std::vector>> MTree::children(const T& value, size_t count = 1) { std::vector>> temp = findByValue(value); if (temp.size() < count) { temp.clear(); return temp; } for (auto pChild : temp[count - 1]->nodeChildren()) collection_.push_back(pChild); return std::move(collection_); } //----< find descendents of node with specified value >---------------------- template void MTree::decendentsHelper(std::shared_ptr> ptr) { collection_.push_back(ptr); for (auto pChild : ptr->nodeChildren()) decendentsHelper(pChild); } template std::vector>> MTree::descendents(const T& value, size_t count = 1) { std::vector>> temp = findByValue(value); if (temp.size() < count) { temp.clear(); return temp; } for (auto pChild : temp[count - 1]->nodeChildren()) decendentsHelper(pChild); return std::move(collection_); } //----< show tree node structure >------------------------------------------- template void showHelper(std::shared_ptr> pNode, size_t levelCount) { std::string spacer(levelCount, ' '); levelCount += 2; std::cout << "\n " << spacer << pNode->value(); for (auto pChild : *pNode) showHelper(pChild, levelCount); levelCount -= 2; } template void show(MTree& tree) { if (tree.root() != nullptr) showHelper(tree.root(), 0); } #endif