迷宫最短路径问题(ShortestPath)的求解——利用链式队列

迷宫最短路径问题(ShortestPath)的求解——利用链式队列

注:借助于栈求解迷宫问题时,并不能保证找到一条从迷宫入口到迷宫出口的最短路径。而借助于队列,可以找到从迷宫入口到迷宫出口的最短路径(如果有的话)。在迷宫中寻找最短路径问题在其他领域也存在,例如,在解决电路布线问题时,一种很常用的方法是在布线区域叠上一个网格,该网格把布线区域划分成n*m个方格,就像迷宫一样。从一个方格a的中心点连接到另一个方格b的中心点时,转弯处必须采取直角,如果已经有某条线路经过一个方格,则封锁该方格。希望使用a和b之间的最短路径来作为布线的路径,以便减少信号的延迟。

1. 迷宫问题的提法

  • 迷宫问题是典型的图的搜索问题。
  • 假设一个迷宫,只有一个入口和一个出口。如果从迷宫的入口到达出口,途中不出现行进方向错误,则得到一条最佳路线。
  • 为此,用一个二维数组maze[m][n]来表示迷宫。
    (1)当数组元素maze[i][j]=1 (0≤i≤m-1,1≤j≤n-1),表示该位置是墙壁,不能通行。
    (2)当数组元素maze[i][j]=0 (0≤i≤m-1,1≤j≤n-1),表示该位置是通路,可以通行。
  • 注:数组的第0行、第m-1行,第0列、第n-1列,必须是迷宫的围墙,即上述行列的所有坐标对应的数值必须为1(除了入口和出口两个位置的坐标对应的数值可以为0以外),不能通行。

2. 利用队列求解最短路径的算法原理

  • 先从位置a开始搜索,把从a可到达的相邻方格都标记为1(表示与a的距离为1)。
  • 然后把从标记为1的方格可到达的相邻方格都标记为2(表示与a的距离为2)。
  • 如此继续标记下去,直到到达位置b或者找不到可到达的相邻方格为止。
  • 按照上述搜索过程,当最后到达b时,就可以在b上读出b与a之间的距离。
  • 为了得到a和b之间的最短路径,从b开始,首先移动到一个比b的标号小的相邻位置上,一定存在这样的相邻位置,因为任一个方格上的标号与它相邻方格上的编号都相差1。
  • 设任一时刻在迷宫中的位置[i][j]标记为X,X周围有4个前进方向,它实际是一系列交通路口,如果某一方向是0值,表示该方向有路可通,反之表示该方向已堵死。
  • 为了有效地选择下一位置,可以将从位置[i][j]出发可能的前进方向预先定义在一个表内,按顺时针方向为Right([i][j+1]),Down([i+1][j]),Left([i][j-1]),Up([i-1][j])。
  • (1)前进方向示意图:
    这里写图片描述
  • (2)前进方向表:

    Move[q].dir move[q].a move[q].b
    “N” -1 0
    “E” 0 1
    “S” 1 0
    “W” 0 -1

3. 利用队列求解最短路径

3.1 链式队列的类定义及其操作的实现
  • 文件:LinkedQueue.h

    
    #ifndef LINKED_QUEUE_H_
    
    
    #define LINKED_QUEUE_H_
    
    
    
    #include <iostream>
    
    
    using namespace std;
    
    template <class T>
    struct LinkNode         //链表结点类的定义
    {
        T data;             //数据域
        LinkNode<T> *link;  //指针域——后继指针
        //仅初始化指针成员的构造函数
        LinkNode(LinkNode<T>* ptr = NULL){ link = ptr; }
        //初始化数据与指针成员的构造函数
        LinkNode(const T& value, LinkNode<T>* ptr = NULL){ data = value; link = ptr; }
    };
    
    template <class T>
    class LinkedQueue
    {
    public:
        LinkedQueue();                      //构造函数
        ~LinkedQueue();                     //析构函数
    public:
        LinkNode<T>* getHead() 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值