///////////////////////////////////////////////////// // MT4Q4 - N-ary Tree with adjacency collection // // // // 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) { _nodes.push_back(pRoot); } bool addNode(Node* pParent, Node* pChild); template void dfs(Node* node, F f); private: Tree(const Tree&); Tree& operator=(const Tree&); std::vector*> _nodes; // could replace with pointer to root }; template bool Tree::addNode(Node* pParent, Node* pChild) { std::vector*>::iterator iter = std::find(_nodes.begin(), _nodes.end(), pParent); if(iter == _nodes.end()) { std::cout << " can't find parent"; return false; } (*iter)->add(pChild); _nodes.push_back(pChild); return true; } 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"); 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"; }