////////////////////////注释部分/////////////////////////
任务:
基于邻接矩阵或邻接表的存储结构,
利用DFS算法解决迷宫问题:给定一个迷宫,
要求输出从入口到出口的所有简单路径,所谓的简单路径是指无圈的路径。
算法简析:获得起点与终点,从起点开始对可行的方向进行上右下左
顺序的路径检索,直到遇到迷宫出口。
全局变量:StType st; //保存现有路径
SavePath p; //保存所有路径
使用结构:box(int i,j,di) //保存节点信息
StType(box data[],int top) //保存路径
SavePath (StType path[],int length) //线性表保存路径
算法优化思路:保存所有路径
每次找到出口,将记录的栈复制到另一个保存结构中
算法步骤:
mgpath :生成路径
函数参数:box start,end 起点与终点
1.起点进栈
2.获取栈顶元素
3.if 栈顶元素为终点
保存路径栈
4.else
while 栈顶元素四个方向探索
if 存在方向可探索
递归可探索方向 //将可探索方向作为起点
CheckNext :检查方向是否可行
函数参数 box next;
if mg[next.i][next.j] = 1;return false
else return true;
////////////////////注释部分////////////////////////
#include
#define MaxSize 25
typedef struct
{
int i; //当前方块的行号
int j; //当前方块的列号
int di; //di是下一可走相邻方块的方位号
} Box; //定义方块类型
typedef struct
{
Box data[MaxSize];
int top; //栈顶指针
} StType; //顺序栈类型,保存路径
typedef struct
{
StType path[10];
int length;
}SavePath;
StType st; //保存现有路径
SavePath p; //保存所有路径
bool pathIf = false;//保存是否存在路径
int M = 4,N =4;
int mg[6][6] = {
{ 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 1, 1 },
{ 1, 0, 1, 0, 0, 1 },
{ 1, 0, 0, 0, 1, 1 },
{ 1, 1, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1 } };
////////////////////////DFS解迷宫/////////////////////
void mgpath (Box start,Box end);
//////////////////////////////////////////////////////
//输出全部路径
void DisPath ()
{
int i,j;
for (i=0; i
{
printf ("第%d条路径:",i+1);
for (j=0; j<=p.path[i].top; j++)
printf ("(%d,%d) ",p.path[i].data[j].i,p.path[i].data[j].j);
printf ("\n");
}
}
int main ()
{
Box start,end;
start.i = start.j = 1;
end.i = end.j = 4;
start.di = end.di = 0;
p.length = 0;
st.top = -1;
int i,j;
printf ("迷宫如下!\n");
for (i=0; i<6; i++)
{
for (j=0; j<6; j++)
{
printf ("%d ",mg[i][j]);
}
printf ("\n");
}
//printf ("start(%d,%d,%d),end(%d,%d,%d)\n",start.i,start.j,start.di,end.i,end.j,start.di);
mgpath (start,end);
if(!pathIf)
printf ("迷宫无解!\n");
else
DisPath (); //输出 SavePath
return 0;
}
/////////////////////////////////////////////////////////
bool CheckNext (Box next)
{
if (mg[next.i][next.j] == 1)
return false;
else
return true;
}
void mgpath (Box start,Box end)
{
Box next;
start.di = 0;
st.top ++;
st.data[st.top] = start;
mg[start.i][start.j] = 1;
//printf ("\n------进栈st.data[%d]:(%d,%d,%d)\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di);
if (start.i==end.i && start.j==end.j) //探索到终点保存路径
{
p.path[p.length] = st;
p.length ++;
pathIf = true;
mg[start.i][start.j] = 0;
//printf ("---出栈st.data[%d]:(%d,%d,%d)mg[%d][%d]=0\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di,start.i,start.j);
st.top--;
//printf ("===========终点!\n");
return ;
}
next = start; //初始化选择方向根源节点
while (start.di<4) //当有可探索方向
{
//printf("对点(%d,%d)探索\n",start.i,start.j);
switch (start.di) //选择探索方向
{
case 0:
//printf("对点(%d,%d)探索上方向\n",start.i,start.j);
next.i--;
if(mg[next.i][next.j]!=1) //对上方向检查是否可行
{
mgpath (next,end);
//printf("继续对点(%d,%d)探索右方向\n\n",start.i,start.j);
}
next.i++;
break;
case 1:
//printf("对点(%d,%d)探索右方向\n",start.i,start.j);
next.j++;
if(mg[next.i][next.j]!=1)//对右方向检查是否可行
{
mgpath (next,end);
//printf("继续对点(%d,%d)探索下方向\n\n",start.i,start.j);
}
next.j--;
break;
case 2:
//printf("对点(%d,%d)探索下方向\n",start.i,start.j);
next.i++;
if(mg[next.i][next.j]!=1)//对下方向检查是否可行
{
mgpath (next,end);
//printf("继续对点(%d,%d)探索左方向\n\n",start.i,start.j);
}
next.i--;
break;
case 3:
//printf("对点(%d,%d)探索左方向\n",start.i,start.j);
next.j--;
if(mg[next.i][next.j]!=1)//对左方向检查是否可行
mgpath (next,end);
//printf ("对点(%d,%d)探索完毕\n\n",start.i,start.j);
mg[start.i][start.j] = 0;
//printf ("---出栈st.data[%d]:(%d,%d,%d)mg[%d][%d]=0\n",st.top,st.data[st.top].i,st.data[st.top].j,st.data[st.top].di,start.i,start.j);
st.top--;
next.j++;
break;
}
start.di ++;
}
}