So I am able to detect cycles oorrectly, but when a node appears twice in a tree in 2 different branches (so without causing an infinite tree in theory), it won't print it. I get why this is, but can't find a solution to this problem.
Also I want this to be iterative, I already got the recursive method.
In general I'd take any solution, but I'd prefer to modify my own of course :)
void node::traverse_stack(ostream& str) {
vector<node*> visited;
// no real stack, because I need to search in it
vector<node*> stack;
visited.push_back(this);
stack.push_back(this);
str << this->get_name() << endl;
int indent = 0;
bool added_child = true;
while (!stack.empty()) {
node* top = stack.back();
added_child = false;
for (int i = 0; i < top->get_nr_children(); i++) {
// if (not added_child and child(i) not in visited)
if (!added_child && find(visited.begin(), visited.end(), top->get_child(i)) == visited.end()) {
indent++;
for (int i = 0; i < indent; i++) {
str << " ";
}
str << top->get_child(i)->get_name() << endl;
visited.push_back(top->get_child(i));
stack.push_back(top->get_child(i));
added_child = true;
}
else {
// if (not added_child and child(i) in stack)
if (!added_child && find(stack.begin(), stack.end(), top->get_child(i)) != stack.end()) {
for (int i = 0; i <= indent; i++) {
str << " ";
}
str << top->get_child(i)->get_name() << " !!!Cycle detected!!!" << endl;
visited.push_back(top->get_child(i));
}
}
}
if (!added_child) {
stack.pop_back();
for (int i = 0; i < top->get_nr_children(); i++) {
visited.erase(find(visited.begin(), visited.end(), top->get_child(i)));
}
indent--;
}
}
}
The trick is to have visited carry just the nodes in the current branch (including duplicates/cycles). This is done by deleting one instance of all child elements when popping the top of the stack.