java 栈如何走迷宫寻路_【数据结构】栈实现迷宫寻路问题

本文介绍了一种利用栈解决迷宫寻路问题的方法。从迷宫入口开始,利用栈保存路径,如果当前位置可通行则继续探索,否则回溯。通过检查当前位置的上、下、左、右四个相邻方块,确定下一步行动。代码示例展示了如何实现这个算法,包括读取迷宫地图、检查可达性、更新最短路径和打印迷宫路径。
摘要由CSDN通过智能技术生成

思路:

解决迷宫求解的问题,从入口出发,顺某一方向向前探索,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置上都能沿原路退回,所以需要用一个后进先出的结构来保存从入口到当前位置的路径。因此,在求迷宫通路的算法中要应用“栈”的思想假设“当前位置”指的是“在搜索过程中的某一时刻所在图中某个方块位置”,则求迷宫中一条路径的算法的基本思想是:若当前位置“可通”,则放入“当前路径”,并继续朝“下一位置”探索,即切换“下一位置”为“当前位置”,如此重复直至到达出口;若当前位置“不可通”,则应顺着“来向”退回到“前一通道块”,然后朝着除“来向”之外的其他方向继续探索;若该通道块的四周4个方块均“不可通”,则应从“当前路径”上删除该通道块。所谓“下一位置”指的是当前位置四周4个方向(上、下、左、右)上相邻的方块。假设以栈Stack记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。由此,“放入路径”的操作即为“当前位置入栈”;“从当前路径上删除前一通道块”的操作即为“出栈”。

代码块

maze.h

#define _CRT_SECURE_NO_WARNINGS 1

#include

#include

#include

#include

using namespace std;

#define N 10

struct pos

{

size_t _row;

size_t _col;

};

stack minstack;

void GetMaze(int arr[][N],int size)

{

FILE* f = fopen("MAP.txt", "r");

if (NULL == f){

cout << "打开文件失败" << endl;

exit(-1);

}

for (int i = 0; i < size; ++i){

for (int j = 0; j < size;){

char ch = fgetc(f);

if (ch == EOF){

cout << "读取地图失败" << endl;

exit(-1);

}

if (ch == '1' || ch == '0'){

arr[i][j] = ch - '0';

++j;

}

}

}

fclose(f);

}

bool CheckIsAccess(int arr[][N],pos next)

{

assert(arr);

if((next._row>=0)&&(next._row<=N)&&(next._col>=0)&&(next._col<=N)&&arr[next._row][next._col]==0)

{

return true;

}

else

{

return false;

}

}

void PrintMaze(int arr[][N],int size)

{

for (int i=0;i

{

for (int j=0;j

{

cout<

}

cout<

}

cout<

}

bool MazePath(int arr[][N],pos entry,stack& path)

{ //找到通路

path.push(entry);

arr[entry._row][entry._col] = 2;

while (!path.empty())

{

pos cur = path.top();

pos next = cur;

if (cur._row == N - 1 || cur._row == 0 || cur._col == N - 1 ){ //更新最短路径

if (minstack.empty())

minstack = path;

else if (path.size() < minstack.size()){

minstack = path;

path.pop();

continue;

}

}

//上

next._row -= 1;

if (CheckIsAccess(arr, next)){

path.push(next);

arr[next._row][next._col] = 2;

continue;

}

next = cur;

//下

next._row += 1;

if (CheckIsAccess(arr, next)){

path.push(next);

arr[next._row][next._col] = 2;

continue;

}

next = cur;

//左

next._col -= 1;

if (CheckIsAccess(arr, next)){

path.push(next);

arr[next._row][next._col] = 2;

continue;

}

next = cur;

//右

next._col += 1;

if (CheckIsAccess(arr, next)){

path.push(next);

arr[next._row][next._col] = 2;

continue;

}

path.pop();

}

if (path.empty()) //判断是否找完所有路径

return true;

return false;

}测试代码块:

#define _CRT_SECURE_NO_WARNINGS 1

#include

#include

#include

#include "maze.h"

using namespace std;

#define N 10

int main(){

int mazeMap[N][N] = { 0 };

GetMaze(mazeMap, N);

PrintMaze(mazeMap, N);

stack path;

pos entry = {2,0}; //定义迷宫入口

bool ret = MazePath(mazeMap,entry,path);

if (ret){

PrintMaze(mazeMap, N);

while (!minstack.empty()){

cout << "" << endl;;

minstack.pop();

}

}

system("pause");

return 0;

}

地图文件

map.txt

1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1

0 0 0 0 0 1 1 1 1 1

1 1 0 1 0 1 1 1 1 1

1 1 0 1 0 0 0 1 1 1

1 1 0 1 1 1 0 1 1 1

1 1 0 1 1 1 0 1 1 1

1 1 0 0 1 1 0 1 1 1

1 1 1 1 1 1 0 1 1 1

1 1 1 1 1 1 0 1 1 1

运行结果图

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值