迷宫

迷宫

注意要自己在你代码当前路径下创建一个MazeMap.txt 
我的MazeMap.txt内容是 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
2 0 0 0 0 0 0 0 1 1 
1 1 0 1 0 1 1 0 1 1 
1 1 0 1 0 0 0 0 1 1 
1 1 0 0 1 0 1 1 1 1 
1 1 1 0 1 0 1 1 1 1 
1 1 1 0 1 0 1 1 1 1 
1 1 1 0 1 0 1 1 1 1

墙是1,路是0,在求最短路径时入口是2,其他情况是1 
详细说明在代码中已经注释 
若有问题和建议请发邮箱blbagony@163.com,欢迎提问和建议

递归版本

代码

 bool GetMazePathR(Pos entry)
{
Pos cur = entry;
Pos next = cur;
_maze[cur._row][cur._col] = 2;

//判断是否到达终点
if (next._row == N-1){return true;}

//上
next = cur;
next._col += 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

next = cur;
next._row += 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

next = cur;
next._col -= 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

//死胡同
_maze[cur._row][cur._col] = 3;
return false;
}

非递归版本

    bool GetMazePath(Pos entry)
{
//给一个入口,然后试探下一个位置
stack<Pos> paths; //paths迷宫路径
paths.push(entry);

while (!paths.empty()) //paths为空证明没有通路
{
Pos cur = paths.top(); //人目前所站的位置
_maze[cur._row][cur._col] = 2; //走过的路标记为2

//判断是否为终点
if (cur._row == M-1)
{
return true;
}

//试探四个方向
Pos next = cur; //试探的节点
//上
next._row -= 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//右
next = cur;
next._col += 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//下
next = cur;
next._row += 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//走到这里是死胡同
Pos back = paths.top();
_maze[next._row][next._col] = 3; //倒回去的路
paths.pop();
}
return false;
}

最短路径非递归

    size_t GetShortPath(Pos entry,stack<Pos>& path, stack<Pos>& shortPath)
{
Pos cur = entry;
path.push(cur);

_maze[cur._row][cur._col] = 2;

if (N-1 == cur._row) //找到通路
{
if (shortPath.empty() || path.size() < shortPath.size())
{ //找最短通路,(最短通路不为空)的时候再赋过去
shortPath = path;
}
}

//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//右
next = cur;
next._col += 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//下
next = cur;
next._row += 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}
//死胡同

_maze[cur._row][cur._col] = 3;
path.pop();
if (path.empty())
return shortPath.size();
}

最短路径递归

    size_t GetShortPathNO(Pos entry,stack<Pos>& path, stack<Pos>& shortPath)
{
Pos cur = entry;
path.push(cur);

/* _maze[cur._row][cur._col] = 2;*/

if (N-1 == cur._row) //找到通路
{
Show();
cout<<endl;
if (shortPath.empty() || path.size() < shortPath.size())
{ //找最短通路,(最短通路不为空)的时候再赋过去
shortPath = path;
}
}

//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; //下一个节点值加一表示走过
GetShortPathNO(next, path, shortPath);
}

//右
next = cur;
next._col += 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}

//下
next = cur;
next._row += 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}
//死胡同

path.pop();
if (path.empty())
return shortPath.size();
}

All_Code

maze.h

#ifndef __MAZE_H__
#define __MAZE_H__
#include <iostream>
#include <windows.h>
#include <stack>
#include <assert.h>
using namespace std;

template<size_t M, size_t N>
class Maze
{
public:
struct Pos //坐标
{
//在外面访问不到
int _col;
int _row;
};
public:
Maze(int maze[M][N])
{
for (size_t i = 0; i < M; ++i)
{
for (size_t j = 0; j < N; ++j)
{
_maze[i][j] = maze[i][j];
}
}
}
//非递归版本
bool GetMazePath(Pos entry)
{
//给一个入口,然后试探下一个位置
stack<Pos> paths; //paths迷宫路径
paths.push(entry);

while (!paths.empty()) //paths为空证明没有通路
{
Pos cur = paths.top(); //人目前所站的位置
_maze[cur._row][cur._col] = 2; //走过的路标记为2

//判断是否为终点
if (cur._row == M-1)
{
return true;
}

//试探四个方向
Pos next = cur; //试探的节点
//上
next._row -= 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//右
next = cur;
next._col += 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//下
next = cur;
next._row += 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next))
{
paths.push(next);
continue; //走下一步
}

//走到这里是死胡同
Pos back = paths.top();
_maze[next._row][next._col] = 3; //倒回去的路
paths.pop();
}
return false;
}

//最短路径
size_t GetShortPath(Pos entry,stack<Pos>& path, stack<Pos>& shortPath)
{
Pos cur = entry;
path.push(cur);

_maze[cur._row][cur._col] = 2;

if (N-1 == cur._row) //找到通路
{
if (shortPath.empty() || path.size() < shortPath.size())
{ //找最短通路,(最短通路不为空)的时候再赋过去
shortPath = path;
}
}

//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//右
next = cur;
next._col += 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//下
next = cur;
next._row += 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next)){GetShortPath(next, path, shortPath);}
//死胡同

_maze[cur._row][cur._col] = 3;
path.pop();
if (path.empty())
return shortPath.size();
}

size_t GetShortPathNO(Pos entry,stack<Pos>& path, stack<Pos>& shortPath)
{
Pos cur = entry;
path.push(cur);

/* _maze[cur._row][cur._col] = 2;*/

if (N-1 == cur._row) //找到通路
{
Show();
cout<<endl;
if (shortPath.empty() || path.size() < shortPath.size())
{ //找最短通路,(最短通路不为空)的时候再赋过去
shortPath = path;
}
}

//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1; //下一个节点值加一表示走过
GetShortPathNO(next, path, shortPath);
}

//右
next = cur;
next._col += 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}

//下
next = cur;
next._row += 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}

//左
next = cur;
next._col -= 1;
if (CheckAccess(next, cur))
{
_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
GetShortPathNO(next, path, shortPath);
}
//死胡同

path.pop();
if (path.empty())
return shortPath.size();
}
//递归版本
bool GetMazePathR(Pos entry)
{
Pos cur = entry;
Pos next = cur;
_maze[cur._row][cur._col] = 2;

//判断是否到达终点
if (next._row == N-1){return true;}

//上
next = cur;
next._col += 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

next = cur;
next._row += 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

next = cur;
next._col -= 1;
if (CheckAccess(next))
{
if (GetMazePathR(next)){return true;}
}

//死胡同
_maze[cur._row][cur._col] = 3;
return false;
}

bool CheckAccess(Pos pos)
{
//检查坐标是否合法
if ((pos._row >= 0 && pos._col < M)
&&(pos._col >= 0 && pos._col <= N)
&& _maze[pos._row][pos._col] == 0)
{
return true;
}
return false;
}

bool CheckAccess(Pos next, Pos cur)
{
//检查坐标是否合法
if ((next._row >= 0 && next._col < M)
&&(next._col >= 0 && next._col <= N))
{
if (_maze[next._row][next._col] == 0){return true;} //通路
else if (_maze[next._row][next._col] == 1){return false;} //死路
else {return _maze[cur._row][cur._col] < _maze[next._row][next._col];} //下一个位置是否为以前走过的并且不是当前通路
}
return false;
}
void Show()
{
for (size_t i = 0; i < N; ++i)
{
for (size_t j = 0; j < M; ++j)
{
cout<<_maze[i][j]<<" ";
}
cout<<endl;
}

}
protected:
int _maze[M][N];
};

void ReadMaze(int maze[10][10])
{
FILE* fout = fopen("MazeMap.txt","r");
assert(NULL != fout);

for (size_t i = 0; i < 10; ++i)
{
for (size_t j = 0; j < 10;)
{
char ch = fgetc(fout);
if ('1' == ch || '0' == ch || '2' == ch)
{
maze[i][j] = ch - '0';
++j;
}
}
}
}

void TestMaze()
{
int maze[10][10];
ReadMaze(maze);
Maze<10,10> m(maze);
Maze<10,10>::Pos entry;
entry._row = 3;
entry._col = 0;
//m.GetMazePath(entry);
//m.GetMazePathR(entry);
stack<Maze<10,10>::Pos> path, shortPath;
int num = m.GetShortPathNO(entry,path, shortPath);
m.Show();
}


#endif //__MAZE_H__

test.cpp

#include "Maze.h"

int main()
{
TestMaze();
system("pause");
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值