这是几个由二维数组构成的迷宫,简单的迷宫,多通路不带环的迷宫,多通路带环的迷宫!对于简单迷宫我们需要判断是否有出口!对于多通路不带环的迷宫我们需要确定出口并且判断最短路径,对于通路间带环的迷宫我们需要找出最短路径!
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。 在本题中也用到的就是回溯, 就是把走过的点坐标压栈,遇到无路可走的情况就开始回溯,也就是出栈! 总体思路就是:
列 == N
即可认为是找到了出口所有代码位于GitHub:https://github.com/zouchanglin/VSworkspace/tree/master/67_Maze,对于简单迷宫的核心代码:
cint CheckAccess(Pos next)
{
//判断越界的情况
if(next._col >= 0 &&next._row>=0
&& next._col<N && next._row<N)
{
//1才是表示通路
if (maze[next._row][next._col] == 1)
{
return 1;
}
}
//return 0表示不可以通过
return 0;
}
int MazeGetPath(Pos entry,Pos exit)
{
Pos cur = entry;//cur记录起始位置
Stack path;
StackInit(&path);
StackPush(&path, entry);//将起始坐标压栈
while (StackEmpty(&path))
{
cur = StackTop(&path);
if ((cur._row == exit._row) && (cur._col == exit._col))
return 1;
//探测下一次可以去的地方
maze[cur._row][cur._col] = 2;//标记上一次走过的位置
//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//下
next = cur;
next._row += 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//左
next = cur;
next._col -= 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//右
next = cur;
next._col += 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//回溯
StackPop(&path);
}
return 0;
}
对于稍复杂的迷宫的核心代码
cint CheckAccess(Pos next)
{
//判断越界的情况
if(next._col >= 0 &&next._row>=0
&& next._col<N && next._row<N)
{
//1才是表示通路
if (maze[next._row][next._col] == 1)
{
return 1;
}
}
//return 0表示不可以通过
return 0;
}
int MazeCheckIsAccess(Pos cur, Pos next)
{
//判断越界的情况
if ((next._col >= 0 && next._row >= 0 && next._col<N && next._row<N)
&&(maze[next._row][next._col] == 1 || maze[next._row][next._col]>maze[cur._row][cur._col]+1))
{
return 1;
}
//return 0表示不可以通过
return 0;
}
int pathsize = 0;
int MazeGetPath(Pos entry,Pos exit)
{
Pos cur = entry;//cur记录起始位置
Stack path;
StackInit(&path);
StackPush(&path, entry);//将起始坐标压栈
maze[entry._row][entry._col] = 2;
while (StackEmpty(&path))
{
cur = StackTop(&path);
maze[cur._row][cur._col] = 2;//标记上一次走过的位置
//if ((cur._row == exit._row) && (cur._col == exit._col))
if (cur._col == 5)
{
//如果只找一条通路则返回
//return 1;
//StackDestory(&path);
if (pathsize == 0||
StackSize(&path) < pathsize)
{
pathsize = StackSize(&path);
}
}
//探测下一次可以去的地方
//上
Pos next = cur;
next._row -= 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//下
next = cur;
next._row += 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//左
next = cur;
next._col -= 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//右
next = cur;
next._col += 1;
if (CheckAccess(next))
{
StackPush(&path, next);
continue;
}
//回溯
StackPop(&path);
}
return 0;
}
int MazeGetShortPath(Pos entry, Pos exit)
{
Pos cur = entry;//cur记录起始位置
Stack path;
StackInit(&path);
StackPush(&path, entry);//将起始坐标压栈
maze[entry._row][entry._col] = 2;
while (StackEmpty(&path))
{
cur = StackTop(&path);
if (cur._col == 5)
{
//如果只找一条通路则返回
//return 1;
//StackDestory(&path);
if (pathsize == 0 ||
StackSize(&path) < pathsize)
{
pathsize = StackSize(&path);
}
}
//探测下一次可以去的地方
//上
Pos next = cur;
next._row -= 1;
if (MazeCheckIsAccess(cur, next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
//下
next = cur;
next._row += 1;
if (MazeCheckIsAccess(cur, next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
//左
next = cur;
next._col -= 1;
if (MazeCheckIsAccess(cur, next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
//右
next = cur;
next._col += 1;
if (MazeCheckIsAccess(cur, next))
{
maze[next._row][next._col] = maze[cur._row][cur._col] + 1;
StackPush(&path, next);
continue;
}
//回溯
StackPop(&path);
}
return 0;
}
本文作者:Tim
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!