开发者

Algorithm finding path in an undirected tree

开发者 https://www.devze.com 2023-02-06 07:06 出处:网络
Suppose I am given a undirected tree and I need to find a path(the only path) between two nodes. What is the best algorithm to do it.I probably could use a Dijkstra\'s algorithm but there a probably

Suppose I am given a undirected tree and I need to find a path(the only path) between two nodes.

What is the best algorithm to do it.I probably could use a Dijkstra's algorithm but there a probably somethi开发者_C百科ng better for trees.

C++ example would be helpful but not necessary

Thank you


Assuming each node has a pointer to its parent, then simply back-track up the tree towards the root from each start node. Eventually, the two paths must intersect. Testing for intersection could be as simple as maintaining a std::map of node addresses.

UPDATE

As you've updated your question to specify undirected trees, then the above isn't valid. A simple approach is simply to perform a depth-first traversal starting at Node #1, eventually you'll hit Node #2. This is O(n) in the size of the tree. I'm not sure there's going to be a faster approach than that, assuming a completely general tree.


Breadth-first search and depth-first search are more effective then Dijkstra's algorithm.


Supposing you have

struct Node
{
    std::vector<Node *> children;
};

then what could be done is traversing the whole tree starting at root keeping the whole chain during the traversal. If you find e.g. node1 then you save the current chain, if you find node2 then you check for the intersection... in code (UNTESTED):

bool findPath(std::vector<Node *>& current_path, // back() is node being visited
              Node *n1, Node *n2,                // interesting nodes
              std::vector<Node *>& match,        // if not empty back() is n1/n2
              std::vector<Node *>& result)       // where to store the result
{
    if (current_path.back() == n1 || current_path.back() == n2)
    {
        // This is an interesting node...
        if (match.size())
        {
            // Now is easy: current_path/match are paths from root to n1/n2
            ...
            return true;
        }
        else
        {
            // This is the first interesting node found
            match = current_path;
        }
    }
    for (std::vector<Node *>::iterator i=current_path.back().children.begin(),
                                       e=current_path.back().children.end();
         i != e; ++i)
    {
        current_path.push_back(*i);
        if (findPath(current_path, n1, n2, match, result))
          return true;
        current_path.pop_back(); // *i
    }
    return false;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消