简体   繁体   中英

Defective Iterative DFS implementation

I have been practicing algorithms and data structures. And I am trying to write an iterative version of DFS.

Here is my code:

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()

However it is not working because I cannot update the loop nextVertex in tos.getConnections(): on the fly as I change tos at the bottom of the loop.

How would you fix that? I know I can do it with recursion but I'd like an iterative solution close to my version.

I think you don't mean to change tos inside your for loop. In DFS you push all adjacent nodes in some arbitrary order onto a stack and when pushing is finished, you take the most recent one, ie the top of stack and keep doing that.

So you don't need this line tos = stack[-1] inside your for loop at all! Also you're popping the recently added node after it's been added in your for loop, which is not what you want. So you need to move stack.pop() line before your for loop. This also makes sense because in DFS you pop (remove) one from stack, push it's adjacent ones, and repeat. So you do this:

    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)

What you instead wanted in your question:

If, for whatever reason (maybe experimenting?), you need to do something that you've described in your question, you may try using a temporary tos for iteration. Like this:

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]

Note that I added only a single line before your for loop and changed the for loop's head a little. And the rest is up to you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM