我将如何递归遍历返回布尔值的树

时间:2020-04-22 07:34:12

标签: c++ tree

在c ++中递归遍历一棵树

2 个答案:

答案 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会更好,因此在节点本身中可以标记的字段也会更好。

这是未经测试的代码。