迷宫问题
2016-04-11 21:14
225 查看
下面是用穷举法来走迷宫
走迷宫的规则:当前坐标是(i, j)下一步可以往四个方向行走,上下左右。
在迷宫数组 0标识可以走,1标识不能走 2 标识已经走过 3标识回退的路
穷举法走出迷宫有两种方法:
1 栈
2 递归
下面通过栈的回溯解决迷宫问题,具体实现如下:
走迷宫的规则:当前坐标是(i, j)下一步可以往四个方向行走,上下左右。
在迷宫数组 0标识可以走,1标识不能走 2 标识已经走过 3标识回退的路
穷举法走出迷宫有两种方法:
1 栈
2 递归
下面通过栈的回溯解决迷宫问题,具体实现如下:
#include<iostream> using namespace std; #include<assert.h> #include<stack> #define N 10 #define M 11 struct Pos { int _row; int _col; }; //获得迷宫 void GetMase(int* a) { assert(a); //fout()打开文件,路径(用“\\”)+名字,"r"读取文件 FILE* fout = (FILE*)fopen("E:\\bite\\stack\\MazeMap.txt","r"); assert(fout); for (int i = 0; i < N; i++) { for (int j = 0; j < M;) { char ch = fgetc(fout);//fgetc获得文件中的字符 if (ch >= '0'&&ch <= '9') { a[i*M + j] = ch - '0'; j++; } } } } //判断迷宫是否可以走出去,利用栈存放和回溯实现 bool SerachMazePath(int* a, Pos entry, stack<Pos>& paths) {//该迷宫0为通路,1标识为死路,2标识已经走过,3标识回退的路 assert(a); paths.push(entry); while (!paths.empty()) { Pos cur = paths.top(); //走过的标记为2 a[cur._row*M + cur._col] = 2; //检查是否到达出口 if (cur._row == N - 1 || cur._col == M - 1) { return true; } Pos next = cur; //向左走 if (cur._col - 1 >= 0 && a[cur._row*M + cur._col - 1] == 0) { next._col--; paths.push(next); continue; } //向右走 if (cur._col + 1 < M && a[cur._row*M + cur._col + 1] == 0) { next._col++; paths.push(next); continue; } //向上走 if ((cur._row - 1) >= 0 && a[(cur._row - 1) * M + cur._col] == 0) { next._row--; paths.push(next); continue; } //向下走 if (cur._row + 1<N && a[(cur._row + 1) * M + cur._col] == 0) { next._row++; paths.push(next); continue; } paths.pop();//回溯 a[cur._row*M + cur._col] = 3; } return false; } void Print(int* a) { assert(a); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { cout << a[i*M + j] << " "; } cout << endl; } }递归实现如下:
//判断迷宫是否可以走出去,利用递归实现 //递归的实现相比较栈减少在回溯时的重复比较,但递归会一直回退到入口处结束 int SerachMazePath(int* a,Pos entry) {//该迷宫0为通路,1标识为死路,2标识已经走过,3标识回退的路 assert(a); Pos cur = entry; //走过的标记为2 a[cur._row*M + cur._col] = 2; Pos next = cur; //检查是否到达出口 if (cur._row != N - 1 && cur._col != M - 1) { //向左走 if (cur._col - 1 >= 0 && a[cur._row*M + cur._col - 1] == 0) { next = cur; next._col--; if(SerachMazePath(a, next)) return 1; a[next._row*M + next._col] = 3; } //向右走 if (cur._col + 1 < M && a[cur._row*M + cur._col + 1] == 0) { next = cur; next._col++; if(SerachMazePath(a, next)) return 1; a[next._row*M + next._col] = 3; } //向上走 if ((cur._row - 1)>=0 && a[(cur._row - 1) * M + cur._col] == 0) { next = cur; next._row--; if(SerachMazePath(a, next)) return 1; a[next._row*M + next._col] = 3; } //向下走 if (cur._row + 1<N && a[(cur._row + 1) * M + cur._col] == 0) {//注意在每进行一步时都需要将next重置,防止一处递归出来后再走某步递归出错 next = cur; next._row++; if(SerachMazePath(a, next)) return 1; a[next._row*M + next._col] = 3; } return 0; } else return 1; }测试用例如下:
void Test1() { int *sm = new int[N * M]; Pos entry; stack<Pos> paths; entry._row = 2; //迷宫入口处 entry._col = 0; GetMase(sm); cout << "是否找到通路:" << SerachMazePath(sm, entry, paths) << endl; Print(sm); } void Test2() { int *sm = new int[N * M]; Pos entry; entry._row = 2; //迷宫入口处 entry._col = 0; GetMase(sm); Print(sm); cout << "是否找到通路:" << SerachMazePath(sm, entry) << endl; Print(sm); }结果如下所示:
相关文章推荐
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- 使用SqlServer CTE递归查询处理树、图和层次结构
- C#中的尾递归与Continuation详解
- C++基于栈实现铁轨问题
- C语言栈的表示与实现实例详解
- C语言实现颠倒栈的方法
- C#递归实现显示文件夹及所有文件并计算其大小的方法
- 算法系列15天速成 第十天 栈
- php递归创建目录的方法
- PHP递归创建多级目录
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- Array栈方法和队列方法的特点说明
- Javascript递归打印Document层次关系实例分析
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- Perl脚本实现递归遍历目录下的文件
- JavaScript的递归之递归与循环示例介绍
- C# 递归查找树状目录实现方法