问题描述
迷宫实验是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒中设置了许多墙,对行进方向形成了多处阻挡。盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。对同一只老鼠重复进行上述实验,一直到老鼠从入口到出口,而不走错一步。老鼠经多次试验终于得到它学习走迷宫的路线。
设计功能要求
迷宫由m行n列的二维数组设置,0表示无障碍,1表示有障碍。设入口为(1,1),出口为(m,n),每次只能从一个无障碍单元移到周围四个方向上任一无障碍单元。编程实现对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。
代码细节:
定义栈
typedef struct Stack
{
int* base;
int* top;
int stacksize;
}Stack;
入栈出栈
void Push(Stack* S, int e) {
//插入栈顶元素为e,由于一开始对于栈的初始化,不必要考虑爆栈的情况
*S->top++ = e;
}
void Pop(Stack* S) {
//若栈不空,则删除S的栈顶元素,用e返回其值
if (S->top == S->base)
{
;
}
else
{
S->top--;
}
}
遍历两个栈,若某一个点的位置坐标刚好处于这两个栈中的同一个位置,那么返回1;否则,返回0。其中count为栈中元素的个数,new_h为新输入的行数,new_l为新输入的列数
int isoverlap(Stack* p, Stack* q, int count, int new_h, int new_l)
{
int* g = p->top;
int* h = q->top;
for (int i = 0; i < count; i++)
{
g--;
h--;
if ((new_h == *g) && (new_l == *h))
{
return 1;
}
}
return 0;
}
访问栈顶元素,count为栈中元素的个数
int visit_top(Stack* p, int count)
{
int* h = p->top;
if (p->base != p->top)
{
h--;
return *h;
}
}
主函数中先输入迷宫矩阵
构造2个栈,并且初始化
Stack* a = (Stack*)malloc(sizeof(Stack));//储存行数
if (!a)
{
exit(0);
}
a->base = (int*)malloc((m * n) * sizeof(int));
if (!a->base)
{
exit(0);
}
a->stacksize = m * n;
a->top = a->base;
Stack* b = (Stack*)malloc(sizeof(Stack));//储存列数
if (!b)
{
exit(0);
}
b->base = (int*)malloc((m * n) * sizeof(int));
if (!b->base)
{
exit(0);
}
b->stacksize = m * n;
b->top = b->base;
具体的迷宫操作,默认入口为(1,1),出口为(m,n)
int x = 0;//即将入栈的行位置
int y = 0;//即将入栈的列位置
Push(a, x);
Push(b, y);
int temp_num = 1;
while ((a->base != a->top) && ((x != m - 1) || (y != n - 1)))
{
if (((y + 1) < n) && (matrix[x][y + 1] == 0))//右
{
if (!isoverlap(a, b, temp_num, x, y + 1))
{
Push(a, x);
Push(b, y + 1);
x = x;
y = y + 1;
temp_num++;
continue;
}
}
if (((x + 1) < m) && (matrix[x + 1][y] == 0))//下
{
if (!isoverlap(a, b, temp_num, x + 1, y))
{
Push(a, x + 1);
Push(b, y);
x = x + 1;
y = y;
temp_num++;
continue;
}
}
if (((y - 1) >= 0) && (matrix[x][y - 1] == 0))//左
{
if (!isoverlap(a, b, temp_num, x, y - 1))
{
Push(a, x);
Push(b, y - 1);
x = x;
y = y - 1;
temp_num++;
continue;
}
}
if (((x - 1) >= 0) && (matrix[x - 1][y] == 0))//上
{
if (!isoverlap(a, b, temp_num, x - 1, y))
{
Push(a, x - 1);
Push(b, y);
x = x - 1;
y = y;
temp_num++;
continue;
}
}
栈顶元素为出口坐标,那么break跳出循环
if ((visit_top(a, temp_num) == m - 1) && (visit_top(b, temp_num) == n - 1))
{
break;
}
无路可走,就开始出栈,与此同时将matrix中相应的位置修改成1,表示此路不通
int s = visit_top(a, temp_num);
int t = visit_top(b, temp_num);
Pop(a);
Pop(b);
x = visit_top(a, temp_num);
y = visit_top(b, temp_num);
matrix[s][t] = 1;
}
if ((visit_top(a, temp_num) == m - 1) && (visit_top(b, temp_num) == n - 1))
{
printf("从入口到出口存在通路!!!");
printf("\n");
the last
int* hang = (int*)malloc(temp_num * sizeof(int));//倒序存储行坐标
int* lie = (int*)malloc((temp_num) * sizeof(int));//倒序存储列坐标
int* v = a->top;
int* u = b->top;
for (int i = 0; i < temp_num; i++)
{
v--;
u--;
hang[i] = *v + 1;
lie[i] = *u + 1;
}
printf("出迷宫走的行序号序列为:");
for (int z = temp_num - 1; z >= 0; z--)
{
printf("%d ", hang[z]);
}
printf("\n");
printf("出迷宫走的列序号序列为:");
for (int z = temp_num - 1; z >= 0; z--)
{
printf("%d ", lie[z]);
}
}
else
{
printf("从入口到出口不存在通路");
}
return 0;