///////////////////////////////////////////////////// // MT4Q4 - N-ary Tree holding only root node // // // // Jim Fawcett, CSE687 - OOD Midterm, Spring 2013 // ///////////////////////////////////////////////////// #include #include #include #include #include "../MTutility/MTutility.h" template class Node { public: typedef std::vector*> Children; Node(const T& t) : _t(t) {} void add(Node* pChild) { _children.push_back(pChild); } Children& children() { return _children; } T& value() { return _t; } private: Children _children; T _t; }; template class Tree { public: typedef void (*NodeProc)(Node* pNode); Tree() {} ~Tree() { // do this only if Tree creates nodes // for(auto pNode : _nodes) delete pNode; } void makeRoot(Node* pRoot) { pRoot_ = pRoot; } Node* root() { return pRoot_; } bool addNode(Node* pParent, Node* pChild); template void dfs(Node* node, F f); private: Tree(const Tree&); Tree& operator=(const Tree&); Node* pRoot_; }; template bool Tree::addNode(Node* pParent, Node* pChild) { class Add { public: Add(Node* pParent, Node* pChild) : pParent_(pParent), pChild_(pChild), foundParent_(false) {} void operator()(Node* pCurrent) { if(pCurrent == pParent_) { pCurrent->add(pChild_); foundParent_ = true; } } bool foundParent() { return foundParent_; } private: Node* pParent_; Node* pChild_; bool foundParent_; }; Add adder(pParent, pChild); dfs(root(), std::ref(adder)); return adder.foundParent(); } template template void Tree::dfs(Node* node, F f) { f(node); for(auto& child : node->children()) dfs(child, f); } template void show(Node* pNode) { std::cout << "\n " << pNode->value() << " has " << pNode->children().size() << " children "; for(auto node : pNode->children()) std::cout << node->value() << " "; } int main() { Title("MT4Q4 - N-Ary Tree holding root node"); typedef Tree sTree; sTree tree; typedef Node sNode; sNode n0("n0"); sNode n1("n1"); sNode n2("n2"); sNode n3("n3"); sNode n4("n4"); sNode n5("n5"); tree.makeRoot(&n0); tree.addNode(&n0, &n1); tree.addNode(&n0, &n2); tree.addNode(&n1, &n3); tree.addNode(&n1, &n4); tree.addNode(&n2, &n5); tree.dfs(&n0, (sTree::NodeProc)show); class NoChild { public: void operator()(Node* pNode) { if(pNode->children().size() == 0) noChildren.push_back(pNode); } std::vector*> noChildNodes() { return noChildren; } private: std::vector*> noChildren; }; NoChild noChild; tree.dfs(&n0, std::ref(noChild)); std::cout << "\n Nodes with no children: "; for(auto node : noChild.noChildNodes()) std::cout << node->value() << " "; std::cout << "\n\n"; }