//迷宫求解,用栈作为工具
//总体思路:先将首格入栈,设空格为0,非空格为1,
//若格子周围有空格则将该空格其入栈,若没则删除栈顶元素并对栈顶元素再找他四周有没有空格
// (只要入栈就将此格设为1,不走回头路。走进死胡同时原路返回,如果迷宫有解,就能回到周边有空格的地方)
//方法一与方法二的区别:
//方法一在结构体内可以只定义格子坐标(二维数组),每次不论是前进还是后退都找一遍四周有没有空格
//方法二要多定义一个方向值(direction)用于表示当前格子到下一格子的关系,这样就不用每次都判断四个方向了
//但方向值只能在确定下一个空格时才能赋值,默认为0,先入栈,再找空格,找到后再赋值
//我用1指北,顺时针方向标号
//若没空格返回上一个格子时,由于上一个格子有方向,可以按方向值查找,可避免走向已经走过的方向
#include<stdio.h>
#include<stdlib.h>
#define MAX 10
#define SPARE 3
//用二维数组初始化迷宫
int mg[10][10] = {
{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}
};
//结构体格子,图方便直接用方法二的了
typedef struct Box
{
int i;
int j;
int di;
}Box;
typedef struct sqstack
{
Box* top;
Box* base;
int size;
}Stack;
void Initstack(Stack* s)
{
s->base = (Box*)malloc(MAX * sizeof(Box));
if (s->base == NULL)
{
printf("开辟动态内存失败\n");
return;
}
s->top = s->base;
s->size = MAX;
}
void Push(Stack* s, Box b)
{
if (s->top - s->base == s->size)
{
s->base = (Box*)realloc(s->base, (s->size + SPARE) * sizeof(Box));
if (s->base == NULL)
{
printf("重新开辟动态内存失败\n");
return;
}
s->top = s->base + s->size;
s->size += SPARE;
}
*s->top++ = b;
}
char Pop(Stack* s)
{
if (s->top == s->base)
{
printf("空栈\n");
return;
}
s->top--;
}
Box Get(Stack* s)
{
return *(s->top - 1);
}
//方法一:
//void Mazepath(int i, int j, int x, int y)
//{
// Stack s;
// Initstack(&s);
// Box b = { i,j,0};
// mg[i][j] = 1;
// Push(&s, b);
// 由于前面已经入栈了起点,而只有格子四周都走不了才会出栈,则栈空只能说明无论怎么走路径都走不到终点
// while (s.base != s.top)
// {
//if(i==x&&j==y)//到达终点
//{
// Box* temp = s.base;
// while (temp != s.top)
// {
// printf("(%d,%d)\n", temp->i, temp->j);
// temp++;
// }
// printf("结束");
// return;
//}
// if (mg[i - 1][j] == 0)
// {
// (s.top - 1)->di = 1;
// Box tb = { --i,j,0 };
// Push(&s, tb);
// mg[i][j] = 1;
// }
// else if (mg[i][j+1] == 0)
// {
// (s.top - 1)->di = 2;
// Box tb = { i,++j,0 };
// Push(&s, tb);
// mg[i][j] = 1;
// }
// else if (mg[i + 1][j] == 0)
// {
// (s.top - 1)->di = 3;
// Box tb = { ++i,j,0 };
// Push(&s, tb);
// mg[i][j] = 1;
// }
// else if (mg[i][j-1] == 0)
// {
// (s.top - 1)->di = 4;
// Box tb = { i,--j,0 };
// Push(&s, tb);
// mg[i][j] = 1;
// }
// else
// {
// Pop(&s);
// i = (s.top - 1)->i;
// j = (s.top - 1)->j;
// }
// }
//}
//方法二:
void Mazepath(int i, int j, int x, int y)
{
Stack s;
Initstack(&s);
Box b = { i,j,0 };
mg[i][j] = 1;
Push(&s, b);
while (s.base != s.top)
{
if (i == x && j == y)
{
Box* temp = s.base;
while (temp != s.top)
{
printf("(%d,%d)\n", temp->i, temp->j);
temp++;
}
printf("结束");
return;
}
int find = 0;
while (((s.top - 1)->di++) < 5 && find == 0)//通过di在刚入栈的格子四周找空格
{
int ti = i;
int tj = j;
switch ((s.top - 1)->di)
{
case 1: ti--; break;
case 2: tj++; break;
case 3: ti++; break;
case 4: tj--; break;
default: break;
}
if (mg[ti][tj] == 0)//如果找到就把坐标还给i,j
{
find = 1;
mg[ti][tj] = 1;//不走回头路
i = ti;
j = tj;
}
}
if (find)
{
Box tb = { i,j,0 };
Push(&s, tb);
}
else//没找到,返回上格
{
Pop(&s);
i = (s.top - 1)->i;
j = (s.top - 1)->j;
}
}
}
int main()
{
Mazepath(1,1,8,8);//四个参数为起点与终点的坐标
}
栈,迷宫,C,C++实现
最新推荐文章于 2024-08-03 12:30:52 发布