数据结构学习之链栈破解迷宫
0x1 问题描述
目的:掌握栈在求解迷宫问题中的应用。
内容:编写一个程序,输出迷宫的所有路径,并求第一条最短路径长度及最短路径。
0x2 解答代码
#include <iostream>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#define MaxSize 100000+7
#define M 8
#define N 8
using namespace std;
typedef int ElemType;
int count=0;
int MinLength=0x3f3f3f3f;
int mg[M+2][N+2]=
{
{1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,0,1,0,1},{1,0,0,0,0,1,1,0,0,1},
{1,0,1,1,1,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,1},
{1,0,1,0,0,0,1,0,0,1},{1,0,1,1,1,0,1,1,0,1},
{1,1,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1}
};
int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
typedef struct
{
int x;
int y;
int di;
}Box;
typedef struct
{
Box data[MaxSize];
int top;
}StType;
//存储最短路径
Box path[MaxSize];
//栈的初始化
void Initstack(StType *&s)
{
s=(StType *)malloc(sizeof(StType));
s->top=-1;
}
//销毁栈
void Destroystack(StType *s)
{
free(s);
}
//判断栈是否为空
bool StackEmpty(StType *s)
{
return(s->top==-1);
}
//进栈
bool Push(StType *&s,Box e)
{
//判断栈满情况
if(s->top==MaxSize-1)
return false;
s->top++;
s->data[s->top]=e;
return true;
}
// 出栈
bool Pop(StType *&s,Box &e)
{
//判断栈空情况
if(s->top==-1)
return false;
e=s->data[s->top];
s->top--;
return true;
}
//取栈顶元素
bool GetTop(StType *&s,Box &e)
{
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
// 返回当前栈的元素个数
int GetLength(StType *s)
{
return(s->top+1);
}
void Disp(StType *s)
{
if(s->top==-1)
cout<< -1 <<endl;
else
{
for(int i=0;i<=s->top;i++)
{
printf("\t(%d,%d)",s->data[i].x,s->data[i].y);
if((i+2)%5==0)
printf("\n");
}
printf("\n");
}
}
bool mgpath(int xi,int yi,int xe,int ye)
{
//存放路径
Box e;
int i,j,di,i1,j1;
bool find;
e.x=xi;e.y=yi;e.di=-1;
mg[xi][yi]=-1;
StType *st;
Initstack(st);
Push(st,e);
while(!StackEmpty(st))
{
//去头元素
GetTop(st,e);
i=e.x,j=e.y,di=e.di;
// cout<<"i:"<<i<<"j:"<<j<<endl;
if(i==xe&&j==ye)
{
count++;
int len=GetLength(st);
printf("第%d条迷宫路径如下: Length:%d\n",count,len);
Disp(st);
if(len<MinLength)
{
MinLength=len;
//存储最短路径
for(int k=0;k<len;k++)
path[k]=st->data[k];
}
/*
int k=0;
while(!StackEmpty(st))
{
Pop(st,e);
path[k++]=e;
}
for(int j=0;j<k;j++)
{
Push(st,path[j]);
}
Pop(st,e);
mg[e.x][e.y]=0;
printf("Length:%d\n",k);
while(k>=1)
{
k--;
printf("\t(%d,%d)",path[k].x,path[k].y);
if((k+2)%5==0)
printf("\n");
}
printf("\n");
//return true;
*/
}
find=false;
while(di<4 && !find)
{
di++;
switch(di)
{
case 0:i1=i-1;j1=j;break;
case 1:i1=i;j1=j+1;break;
case 2:i1=i+1;j1=j;break;
case 3:i1=i;j1=j-1;break;
}
if(mg[i1][j1]==0) find=true;
}
if(find)
{
st->data[st->top].di=di;
e.x=i1;e.y=j1;e.di=-1;
Push(st,e);
mg[i1][j1]=-1;
}else
{
Pop(st,e);
mg[e.x][e.y]=0;
}
}
Destroystack(st);
return false;
}
//求解主程序
int main()
{
int sx=1,sy=1;
int es=8,ey=8;
mgpath(sx,sy,es,ey);
if(count!=0)
{
cout<< "total num:"<<count<<endl;
cout<< "最短路径为: Length:"<<MinLength<<endl;
for(int k=0;k<MinLength;k++)
{
printf("\t(%d,%d)",path[k].x,path[k].y);
if((k+2)%5==0)
printf("\n");
}
}else
{
cout<<-1<<endl;
}
return 0;
}
0x3 结果
0x4 总结
其实就是dfs的思想,细节处理下,路径保存下就行了。