我正在阅读深度优先搜索(here),并想知道为什么我们不返回递归调用的值。这可能听起来很奇怪,所以这里有代码行的代码注释:
def depthFirst(node, soughtValue, visitedNodes):
if node.value == soughtValue:
return True
visitedNodes.add(node)
for adjNode in node.adjacentNodes:
if adjNode not in visitedNodes:
if depthFirst(adjNode, soughtValue, visitedNodes): # why this?
return True
return False
我的问题:将替换:
if depthFirst(adjNode, soughtValue, visitedNodes):
return True
与
return depthFirst(adjNode, soughtValue, visitedNodes):
通过过早评估False
来缩短搜索范围?有问题的线似乎是按照当前adjNode
说的,看看它是否会导致解决方案;如果确实如此,我们将从叶子中获取一系列True
语句一直返回到搜索的开头(我们当前的adjNode
);这种情况一直发生在根(搜索的开始和第一次递归调用)。只有这样我们才能说我们找到了一条有效路径并返回'True'。
似乎第一个return语句触发了'True'语句链,我们将搜索保留在循环中。我对么?有很多事情发生,任何进一步的解释将不胜感激。
答案 0 :(得分:1)
假设我们有以下图表:
1 ——— 2
|
4 ——— 5 ——— 6
| | |
7 ——— 8 ——— 9
其中seekValue是节点9。 从节点1开始作为源:
wrong code:
===========
dfs(1,9,…) dfs(2,9,…)
… …
// neighbors // neighbors
return dfs(2,9,…) <———| NO return dfs(1,9,…) as 1 has been visited
return dfs(4,9,…) |
|
| so return false
| |
|-------------|
result
dfs(1,9,…) terminates with a false even without going to dfs(4,9,…)
correct code:
============
dfs(1,9,…) dfs(2,9,…)
… …
// neighbors // neighbors
if (dfs(2,9,…)) <———| NO if dfs(1,9,…) as as 1 has been visited
return true | return true
|
if (dfs(4,9,…)) |
return true |
|
| so return false
| |
|-------------|
result
dfs(1,9,…) doesn't terminate and does continue to other neighbors (i.e., dfs(4,9,…)) and so on until we reach the soughtValue 9 and return true
答案 1 :(得分:0)
我们无法返回任何值,因为如果它是False
,则for
循环会中断并且永远不会找到可能更晚的True
。
示例:
def divisible_by_five_A():
for n in range(100):
if n and not n % 5:
return n, 1
divisible_by_five_A()
# O: 5, 1
VS
def divisible_by_five_B():
for n in range(100):
return n, (n and not n % 5)
divisible_by_five_B()
# O: 0, 0
答案 2 :(得分:0)
是的,如果depthFirst(adjNode, soughtValue, visitedNodes)
返回False
,则搜索需要继续。只有当您在图表的该部分找到了所需的值时,您才能返回True
进行搜索。
如果您要用return depthFirst(adjNode, soughtValue, visitedNodes)
替换它,那么您将只搜索该部分图形中的值(从该相邻节点开始),但如果值为n,则不会继续搜索在那里找到了。