在c ++中递归遍历一棵树
答案 0 :(得分:0)
#include <iostream>
#include <vector>
struct Node
{
// some other stuff...
int id;
std::vector<Node*> children;
};
bool finder(Node* root, Node* currentNode, std::vector<bool>& visited)
{
visited[currentNode->id] = true;
for (Node* node : currentNode->children)
if (node == root)
{
std::cout << currentNode->id << '\n';
return true;
}
else if (!visited[node->id] && finder(root, node, visited))
{
return true;
}
visited[currentNode->id] = false;
return false;
}
bool Looper(Node* root, int n)
{
std::vector<bool> visited(n, false);
return finder(root, root, visited);
}
int main()
{
Node n0{ 0 };
Node n1{ 1 };
Node n2{ 2 };
Node n3{ 3 };
n0.children.push_back(&n1);
n0.children.push_back(&n2);
n1.children.push_back(&n3);
n3.children.push_back(&n0);
if (Looper(&n0, 4))
std::cout << "Found\n";
}
输出:
3
Found
由于您想要一个指向父节点的子节点,因此您的树将包含循环。因此,您必须跟踪访问过的节点。这就是为什么我要跟踪访问的节点的原因。我也建议使用std::vector
来表示树,而不要使用节点。
答案 1 :(得分:0)
这是我对您的任务的理解,只需用树的根节点和一个空向量调用check_for_cycles
即可检测树中的循环。
bool check_for_cycles(Node* node, vector<Node*>& visited)
{
// null is a not a cycle
if (node == nullptr)
return false;
// have we been here before? if so we have a cycle
if (find(visited.begin(), visited.end(), node) != visited.end())
return true;
// mark this node as visited
visited.push_back(node);
// recursively check the sub trees
return check_for_cycles(node->left, visited) || check_for_cycles(node->right, visited);
}
请注意,向量不是访问的最佳选择,因为检查节点是否存在会花费时间。一个unordered_map会更好,因此在节点本身中可以标记的字段也会更好。
这是未经测试的代码。