python栈实战 迷宫寻找出口

        迷宫问题,作为计算机科学和算法设计中的一个经典问题,不仅考验了我们对数据结构的理解和应用,还锻炼了我们解决复杂问题的能力。在众多的解决方案中,利用栈来实现深度优先搜索(DFS)是一种直观且高效的方法。

        栈,作为一种基础的数据结构,其特性使得它在处理需要回溯的场景时显得尤为合适。在迷宫问题中,当我们沿着某条路径深入探索时,可能会遇到无法继续前行的死胡同。此时,栈的作用就凸显出来了:我们可以将当前的位置(以及可能的其他状态信息)压入栈中,然后回溯到上一个决策点,尝试其他可能的路径。这种“试错”与“回溯”的过程,正是栈在迷宫问题中的核心应用。

        本段代码将展示如何使用Python中的栈,来解决一个二维迷宫问题。我们将通过定义迷宫的结构、初始化栈、编写DFS逻辑以及处理边界条件和终止条件等步骤,逐步构建出一个完整的迷宫求解算法。希望读者在跟随代码实现的过程中,能够深入理解栈在迷宫问题中的应用,以及DFS算法的基本思想。

        为了锻炼思维,我使用的是一个链式栈,大家也可以用列表模拟栈,用顺序栈的方法。

一、首先初始化栈

class node:
    def __init__(self,pos):
        self.pos=pos
        self.next=None

class stack:
    def __init__(self):
        self.top=node(None)
    def isempty(self):
        return self.top==None
    def push(self,pos):
        new_node=node(pos)
        if self.isempty():
            self.top.next=new_node
        else:
            new_node.next=self.top.next
            self.top.next=new_node
    def pop(self):
        node=self.top.next
        self.top.next=node.next
        return node
    def print_all(self):
        n=self.top.next
        while n:
            print(n.pos,end=' ')
            n=n.next

在我的代码中,node作为结点存放的pos是坐标,存储方式是一个二元组记录x轴与y轴坐标

二、然后初始化地图,定义初始位置,定义栈用来存放走过的路径

class find_road:
    def __init__(self):
        self.map=None
        #读取存档里的地图
        self.read_map()
        #记录当前位置
        self.pos_x=0
        self.pos_y=0
        #定义走过的路
        self.road=stack()

    def read_map(self):
        with open('map.json','r',encoding='utf-8') as f:
            self.map=json.loads(f.read())         

在find_road类中定义get_exit()方法

    def get_exit(self):
        while self.pos_x!=18 and self.pos_y!=18:
            #判断右边能走就往右走
            if self.map[self.pos_x+1][self.pos_y]==' ':
                #同时填上之前走的路防止重复走
                self.map[self.pos_x][self.pos_y]='#'
                self.pos_x+=1
                #将走过的路保存到栈里面
                self.road.push((self.pos_x,self.pos_y))    
            elif self.map[self.pos_x][self.pos_y+1]==' ':
                self.map[self.pos_x][self.pos_y]='#'
                self.pos_y+=1            
                self.road.push((self.pos_x,self.pos_y))
            elif self.map[self.pos_x-1][self.pos_y]==' ':
                self.map[self.pos_x][self.pos_y]='#'
                self.pos_x-=1
                self.road.push((self.pos_x,self.pos_y))    
            elif self.map[self.pos_x][self.pos_y-1]==' ':
                self.map[self.pos_x][self.pos_y]='#'
                self.pos_y-=1            
                self.road.push((self.pos_x,self.pos_y))
            else:
                #发现那条路也走不了就说明上一步走的错误需要退回上一步重新走
                pos=self.road.pop().pos
                #同时标记这条路防止下一次再走
                self.map[self.pos_x][self.pos_y]='#'
                self.pos_x=pos[0]
                self.pos_y=pos[1]
        print('找到出口')
        self.road.print_all()

因为出口在右下角初始位置在左上角,所以我们认为优先往右或下面走会跟快的找到出口。在右和下都不能走的情况下,我们再选择左上,在被封死的情况下,说明我们上一步走进死胡同了,我们需要实现倒退的操作,即退栈。并且堵住刚刚的路口,避免下次再尝试。最终如果我们走到了(18,18)即认为,我们找到了出口。

在这段代码中我没有考虑溢出的情况,即走出20x20的地图。这是因为地图四周都是‘#’,程序在寻找出口的时候不会跳出墙。

最终运行结果:我们发现路径是倒着的。这是因为栈先入先出的原则,要想整个输出只能从top开始往下索引。

下面,我提供几个有效思路:

1、用另一个栈承载当前的栈,这样可以把当前栈颠倒一下

2、用顺序栈即列表模拟,最后倒着输出即可

3、设置终点在(0,0),然后设置出发点在(18,18)优先往左上走,最终得到的结果就是预期的答案

你可能感兴趣的:(深度优先,算法)