【发布时间】:2013-02-23 09:06:00
【问题描述】:
我为 DFS 非递归编写了一个解决方案,但我无法修改它以进行拓扑排序:
def dfs(graph,start):
path = []
stack = [start]
while stack != []:
v = stack.pop()
if v not in path: path.append(v)
for w in reversed(graph[v]):
if w not in path and not w in stack:
stack.append(w)
return path
任何想法如何修改它?
使用递归版本,我可以轻松进行排序:
def dfs_rec(graph,start,path):
path = path + [start]
for edge in graph[start]:
if edge not in path:
path = dfs_rec(graph, edge,path)
print start
return path
输入:
>>> graph = {
1: [2, 3],
2: [4, 5, 6],
3: [4,6],
4: [5,6],
5: [6],
6: []
}
>>> dfs_rec(graph,1,[])
6
5
4
2
3
1
[1, 2, 4, 5, 6, 3]
>>> dfs(graph,1)
[1, 2, 4, 5, 6, 3]
>>> graph = {
1: [3],
3: [5,6],
5: [4],
4: [7],
7: [],
6: []
}
>>> print dfs_rec(graph,1,[])
7
4
5
6
3
1
[1, 3, 5, 4, 7, 6]
>>> print dfs(graph,1)
[1, 3, 5, 4, 7, 6]
所以我也需要在非递归中得到这个排序。
非递归解:
我认为这也可能是解决方案,如果我错了,请标记我。
def dfs(graph,start):
path = []
stack = [start]
label = len(graph)
result = {}
while stack != []:
#this for loop could be done in other ways also
for element in stack:
if element not in result:
result[element] = label
label = label - 1
v = stack.pop()
if v not in path: path.append(v)
for w in reversed(graph[v]):
if w not in path and not w in stack:
stack.append(w)
result = {v:k for k, v in result.items()}
return path,result
输入:
graph = { 1: [3], 3:[5,6] , 5:[4] , 4:[7], 7:[],6:[]}
print dfs(graph,1)
输出:
([1, 3, 5, 4, 7, 6], {1: 7, 2: 4, 3: 5, 4: 6, 5: 3, 6: 1})
1
/
3
/\
5 6
/
4
/
7
【问题讨论】:
-
你能举个输入的例子吗?
-
这里有什么问题?在这两种情况下,
dfs_rec的返回值都与dfs的返回值相匹配。你想要什么结果? -
是的结果匹配,但是在递归结束时在 dfs_rec 中它给了我(通过打印开始)图的拓扑排序,所以现在我想对非递归进行拓扑排序功能(dfs),但我无法成功。
-
那么你希望两个函数在第二种情况下都返回
[7, 4, 5, 6, 3, 1]? -
[6, 5, 4, 2, 3, 1] 和 [7, 4, 5, 6, 3, 1] 用于 dfs(graph,1) 非递归函数。如您所见,我已经为第一个函数 dfs_rec 提供了它。