在大多数情况下,我们在能使用 BFS 时也可以使用 DFS。但是有一个重要的区别:遍历顺序
。
与 BFS 不同,更早访问的结点可能不是更靠近根结点的结点。因此,你在 DFS 中找到的第一条路径可能不是最短路径。
在DFS中,想要捋清楚搜索顺序,可以画一个树来表示代码执行步骤,以此来确定 搜索入口 和 搜索边界
模板-递归
/*
* Return true if there is a path from cur to target.
*/
boolean DFS(Node cur, Node target, Set<Node> visited)
{
if cur is target
return true ;
for (next : each neighbor of cur)
{
if (next is not in visited)
{
add next to visted;
if DFS(next, target, visited) == true;
return true
}
}
return false;
}
栈的大小正好是 DFS 的深度。因此,在最坏的情况下,维护系统栈需要 O(h),其中 h 是 DFS 的最大深度。在计算空间复杂度时,永远不要忘记考虑系统栈。
模板-显式栈
递归解决方案的优点是它更容易实现。 但是,存在一个很大的缺点:如果递归的深度太高,你将遭受堆栈溢出。 在这种情况下,你可能会希望使用 BFS,或使用显式栈实现 DFS。
这里有一个使用显式栈的模板,它使用 while 循环和栈来模拟递归期间的系统调用栈:
/*
* Return true if there is a path from cur to target.
*/
boolean DFS(int root, int target)
{
Set<Node> visited;
Stack<Node> s;
add root to s;
while (s is not empty)
{
Node cur = the top element in s;
if cur is target
return true;
for (Node next : the neighbors of cur)
{
if (next is not in visited)
{
add next to s;
add next to visited;
}
}
remove cur from s;
}
return false;
}