假设我被赋予了一个无向树,我需要在两个节点之间找到一条路径(唯一的路径)。
最好的算法是什么。我可能会使用Dijkstra的算法,但树木可能更好。
C ++示例会有所帮助,但不是必需的
谢谢
答案 0 :(得分:6)
假设每个节点都有一个指向其父节点的指针,那么只需从每个起始节点向后追溯树的根。最终,两条路径必须相交。测试交集可以像维护std::map
节点地址一样简单。
<强>更新强>
当您更新问题以指定无向树时,上述内容无效。一个简单的方法就是从节点#1开始执行深度优先遍历,最终你会遇到节点#2。这是树的大小 O(n)。假设有一个完全通用的树,我不确定会有更快的方法。
答案 1 :(得分:1)
假设你有
struct Node
{
std::vector<Node *> children;
};
然后可以做的是从遍历整个树遍历整个链,在遍历期间保持整个链。如果您发现例如node1然后保存当前链,如果找到node2然后在代码中检查交叉点...( 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;
}
答案 2 :(得分:1)
广度优先搜索和深度优先搜索比Dijkstra算法更有效。