算法:栈与队列的经典案例,模拟迷宫算法

在这里插入图片描述

模拟迷宫

# 1代表墙壁0代表通道
maze = [
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 1, 0, 0, 0, 1, 0, 1],
    [1, 0, 0, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 0, 0, 0, 1],
    [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
    [1, 0, 1, 0, 0, 0, 1, 0, 0, 1],
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
    [1, 1, 0, 0, 0, 0, 0, 0, 0, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]

栈思路 == 深度优先搜索

# 封装四个方向列表
dirs = [
    lambda x, y: (x + 1, y),
    lambda x, y: (x - 1, y),
    lambda x, y: (x, y - 1),
    lambda x, y: (x, y + 1)
]


# 用栈的思路
def maze_path(x1, y1, x2, y2):
    """x1起点 x2终点"""
    stack = [(x1, y1)]
    # 栈不空就循环(栈空代表没有路了)
    while len(stack) > 0:
        curNode = stack[-1]  # 当前节点位置
        if curNode[0] == x2 and curNode[1] == y2:
            print('找到迷宫出路')
            for p in stack:
                print(p)
            break
        # 下一个点 上(x-1,y)、下(x+1,y)、左(x,y-1)、右(x,y+1)
        for di in dirs:
            nextNode = di(curNode[0], curNode[1])
            # 如果下一个节点能走
            if maze[nextNode[0]][nextNode[1]] == 0:
                # 能走就加到栈里
                stack.append(nextNode)
                maze[nextNode[0]][nextNode[1]] = 2  # 随便标记一个数代表之前走过
                break
        else:
            # 如果一个都找不到就回退
            maze[curNode[0]][curNode[1]] = 2  # 这个位置也要标记为走过了
            stack.pop()  # 出栈

    else:
        print('该迷宫没有出路')
        return False


# 测试效果
maze_path(1, 1, 8, 8)

队列思路 == 深度优先搜索

from collections import deque


# 封装四个方向列表
dirs = [
    lambda x, y: (x + 1, y),
    lambda x, y: (x - 1, y),
    lambda x, y: (x, y - 1),
    lambda x, y: (x, y + 1)
]


def print_r(path):
    real_path = []  # 真实路径
    i = len(path) - 1
    while i >= 0:
        real_path.append(path[i][0:2])
        i = path[i][2]
    real_path.reverse()
    for node in real_path:
        print(node)


# 广度优先: 同时考虑多条路
def maze_path_queue(x1, y1, x2, y2):
    queue = deque()
    path = []  # 初始的时候起点坐标放进去,额外的列表存储
    queue.append((x1, y1, -1))  # -1为记录而已
    # 队列空代表没有路
    while len(queue) > 0:
        cur_Node = queue.popleft()  # 从左边出去
        path.append(cur_Node)  # 加入
        if cur_Node[0] == x2 and cur_Node[1] == y2:
            print('找到迷宫出路')
            print_r(path)
            return True

        for di in dirs:
            # 下一个节点
            next_node = di(cur_Node[0], cur_Node[1])
            # 如果可以走就进队
            if maze[next_node[0]][next_node[1]] == 0:
                # len(path)-1) 表示 cur_Node在当前的下标
                queue.append((next_node[0], next_node[1], len(path) - 1))
                maze[next_node[0]][next_node[1]] = 2  # 标记已走过
    return False


# 测试效果
maze_path_queue(1, 1, 8, 8)

猜你喜欢

转载自blog.csdn.net/weixin_42329277/article/details/84550120
今日推荐