网格 最短路径 php,队列求解网格中任意两点间最短路径

任意的m * n 网格,用户指定起点,终点和障碍物,寻找一条起点到终点间的最短路径。

用户输入时将无障碍物区域置为0,将障碍物置1

为了方便计算,将起点的值置为2,然后在起点的四个方面寻找可走区域,将其放入队列,并将其值置为3,再到3所有标记为3的周围寻找可走区域(0)并其值设置为4,依此规则循环下去,直到终点被标记为止,如果无法标记到终点则这两点间走不通

代码如下:

/*寻找一条网格中两点间的最短路径*/

#include

#include

using namespace std;

struct position

{

short xPos;

short yPos;

};

position start, finish;

short **grid;

short m, n;//m,n分别表示网格行列数

short pathLength;

position* path;//存储路径

//函数声明

void inputGrid();

bool findPath();

ostream& operator << (ostream& out, position& m);

void printPath();

int main()

{

inputGrid();

if (findPath())

printPath();

else

cout << "无法从起点走到终点!" << endl;

return 0;

}

void inputGrid()

{/*不进行异常处理*/

cout << "please input the size: (row and column)" << endl;

cin >> m >> n;

grid = new short*[m + 2];

for (int i = 0;i < m + 2;i++)

grid[i] = new short[n + 2];

cout << "please input the maze:" << endl;

for (int i = 1;i < m + 1;i++)

for (int j = 1;j < n + 1;j++)

cin >> grid[i][j];

cout << "please input the start position :" << endl;

cin >> start.xPos >> start.yPos;

cout << "please input the finish position :" << endl;

cin >> finish.xPos >> finish.yPos;

//初始化边界

for (int i = 0;i < m + 2;i++)

grid[i][0] = grid[i][n + 1] = 1;

for (int j = 0;j < n + 2;j++)

grid[0][j] = grid[m + 1][j] = 1;

}

bool findPath()

{

if ((start.xPos == finish.xPos) && (start.yPos == finish.yPos))

{

pathLength = 0;

return true;

}

position offset[4];

offset[0].xPos = 0;offset[0].yPos = 1;//向右

offset[1].xPos = 1;offset[1].yPos = 0;//向下

offset[2].xPos = 0;offset[2].yPos = -1;//向左

offset[3].xPos = -1;offset[3].yPos = 0;//向上

position here = start;

grid[start.xPos][start.yPos] = 2;

const int numberOfNeighbour = 4;

//对可达到位置做标记

queue q;

position neighbour;

while (true)

{

for (int i = 0;i < 4;i++)

{//检查相邻位置

neighbour.xPos = here.xPos + offset[i].xPos;

neighbour.yPos = here.yPos + offset[i].yPos;

if (grid[neighbour.xPos][neighbour.yPos] == 0)

{

grid[neighbour.xPos][neighbour.yPos] = grid[here.xPos][here.yPos] + 1;

//标记到达终点处

if ((neighbour.xPos == finish.xPos) && (neighbour.yPos == finish.yPos))

break;

//把here相邻的可走通路插入队列

q.push(neighbour);

}

}

//判断是否到达终点

if ((neighbour.xPos == finish.xPos) && (neighbour.yPos == finish.yPos))

break;

if (q.empty())

return false; //不能标记到终点处

here = q.front();

q.pop();

}

pathLength = grid[finish.xPos][finish.yPos] - 2;

path = new position [pathLength];

here = finish;

for (int i = pathLength - 1;i >= 0;i--)

{

path[i] = here;

for (int j = 0;j < numberOfNeighbour;j++)

{

neighbour.xPos = here.xPos + offset[j].xPos;

neighbour.yPos = here.yPos + offset[j].yPos;

if (grid[neighbour.xPos][neighbour.yPos] == i + 2)

break;

}

here = neighbour;

}

return true;

}

//重载<<

ostream& operator << (ostream& out, position& m)

{

out << "(" << m.xPos << "," << m.yPos << ")" ;

return out;

}

void printPath()

{

cout << "最短的一条路径为:" << endl;

for (int i = 0;i < pathLength;i++)

cout << path[i] << endl;

}运行结果如下:

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值