I have a class ‘Class’ which has a member std::list, I want to search that list/tree for an item, specifically an item with a specific name. A basic representation of my class is as follows:
#include <list> #include <string> class Class { std::string _name; std::list<Class*> _members; public: Class(const std::string& name) : _name(name) {} void addMember(Class* member) { _members.push_back(member); } const std::string& name() const { return _name; } const std::list members() const { return _members; } Class* findItem(const std::string& name) const { ... } };
I could just do something like this in Class::findItem:
Class* Class::findItem(const std::string& n) const { std::list<Class>::const_iteratior i; for(i=_members.begin(); i!=_members.end(); ++i) if((*i)->name() == n) return *i; for(i=_members.begin(); i!=_members.end(); ++i) { Class* cls = (*i)->findItem(n); if(cls) return cls; } return 0; }
But, what I want to happen is for findItem() to return the ‘closest’ item to the one searched from. For instance, if this is my tree, with each letter representing one level in the list hierarchy, and each number representing the items ‘value’. I want findItem(3) to return B(3), rather than C(3).
A(1) | ---------------------------------- B(2) B(3) | | --------------------- ----- C(3) C(4) C(4) | | ---------------- ---------- D(5) D(6) D(7) D(5) D(6)
Use a breadth-first search. As you access a node that isn’t equal to the query value, you push that node onto the back of the queue. Process nodes from the front of the queue first. The first match you find will be the one closest to the root.