Iterative DFS实施有缺陷

问题描述 投票:1回答:1

我一直在练习算法和数据结构。我正在尝试编写DFS的迭代版本。

这是我的代码:

def dfsvisit_iterative(self,startVertex):
    stack = []
    stack.append(startVertex)
    startVertex.setColor('gray')
    self.time += 1
    startVertex.setDiscovery(self.time)

    while stack:
        tos = stack[-1]

        for nextVertex in tos.getConnections():
            if nextVertex.getColor() == 'white':
                nextVertex.setColor('gray')
                nextVertex.setPred(tos)
                self.time += 1
                nextVertex.setDiscovery(self.time)
                stack.append(nextVertex)
                tos = stack[-1]

        tos.setColor('black')
        self.time += 1
        tos.setFinish(self.time)
        stack.pop()

然而它不起作用,因为我无法动态更新循环nextVertex in tos.getConnections():,因为我在循环的底部更改tos

你会如何解决这个问题?我知道我可以用递归来做,但我想要一个接近我的版本的迭代解决方案。

python python-3.x algorithm depth-first-search
1个回答
0
投票

我想你并不是要改变你的for循环中的tos。在DFS中,您将所有相邻节点以任意顺序推送到堆栈上,当推送完成时,您将获取最新的节点,即堆栈顶部并继续执行此操作。

所以你根本不需要在你的for循环中使用这行tos = stack[-1]!在你的for循环中添加了节点后,你也会弹出最近添加的节点,这不是你想要的。因此,您需要在for循环之前移动stack.pop()行。这也是有道理的,因为在DFS中你从堆栈弹出(删除)一个,推送它的相邻的,然后重复。所以你这样做:

    while stack:
        tos = stack[-1]
        stack.pop()

        for nextVertex in tos.getConnections():
            if nextVertex.getColor() == 'white':
                nextVertex.setColor('gray')
                nextVertex.setPred(tos)
                self.time += 1
                nextVertex.setDiscovery(self.time)
                stack.append(nextVertex)

        tos.setColor('black')
        self.time += 1
        tos.setFinish(self.time)

您在问题中想要的是什么:

如果,无论出于何种原因(可能正在试验?),你需要做一些你在问题中描述的事情,你可以尝试使用临时的迭代来进行迭代。像这样:

while stack:
        tos = stack[-1]
        temp_tos = tos

        for nextVertex in temp_tos.getConnections():
            if nextVertex.getColor() == 'white':
                nextVertex.setColor('gray')
                nextVertex.setPred(tos)
                self.time += 1
                nextVertex.setDiscovery(self.time)
                stack.append(nextVertex)
                tos = stack[-1]

请注意,我在for循环之前只添加了一行,并且稍微更改了for循环的头部。其余的由你决定。

© www.soinside.com 2019 - 2024. All rights reserved.