#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100 //最大存储坐标的空间
int count = 0;
int END_X, END_Y; //定义一个全局变量,用来表征迷宫结束的行与列的下标参数
typedef struct
{
int x; //表示存储行的位置
int y; //表示存储列的位置
int di; //表示存储方位,1234分别代表右下左上
}Pos;
typedef struct //定义一个顺序栈表
{
Pos Addr[MAXSIZE]; //定义一个地址数组
int top; //顶针指示器
}Stack;
//置空栈
Stack *Init_Stack()
{
Stack *s;
s = malloc(sizeof(Stack));
s->top = -1;
return s;
}
//判空栈
Empty_Stack(Stack *s)
{
if (s->top == -1) return 1;
else
return 0;
}
//入栈操作
int Push_Stack(Stack *s, int x, int y, int di)
{
if (s->top == MAXSIZE - 1) return 0; //栈满,不能入栈
else
{ //否则将元素入栈
s->top++;
s->Addr[s->top].x = x;
s->Addr[s->top].y = y;
s->Addr[s->top].di = di;
count++;
return 1;
}
}
//元素出栈
int Pop_Stack(Stack *s, int *x, int *y, int *di)
{
if (Empty_Stack(s)) return 0;//栈空不能出栈
else
{
*x = s->Addr[s->top].x;
*y = s->Addr[s->top].y;
*di = s->Addr[s->top].di;
s->top--;
count++;
return 1;
}
}
// 迷宫主题部分
void menu()
{
printf("\n\n\t\t------------------------欢迎来到我的迷宫----------------------------\n");
printf("\t\t>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
printf("\t\t<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
printf("\t\t--------------------------------------------------------------------\n");
}
int Print_MAZE(int *q) // 定义并打印迷宫
{
int i, j;
printf("\t\t 列标→");
for (i = 1; i < 9; i++)
printf("%4d", i);
printf("\n");
for (i = 0; i < 11; i++)
{
printf("\t\t\t");
for (j = 0; j < 10; j++)
printf("%4d", *q++);
printf("\n");
}
return 1;
}
//迷宫求解函数
answer_maze(Stack *s, int MAZE[11][10], int x, int y, int di)
{
printf("第%d步:", count);
printf("(%d,%d,%d)\n", x, y, di);
if (x ==END_X&&y ==END_Y)
{
printf("到达出口坐标共走了%d步\n", count); return 0;
}
else if (MAZE[x][y + 1] == 0) //下面四段分支结构分别表示该位置的右下左上四个方向可以通行的情况
{
di = 1;
Push_Stack(s, x, y, di);
y += 1;
MAZE[x][y - 1] = 1;
MAZE[x][y] = 1;
}
else if (MAZE[x + 1][y] == 0)
{
di = 2;
Push_Stack(s, x, y, di);
x += 1;
MAZE[x - 1][y] = 1;
MAZE[x][y] = 1;
}
else if (MAZE[x][y - 1] == 0)
{
di = 3;
Push_Stack(s, x, y, di);
y -= 1;
MAZE[x][y + 1] = 1;
MAZE[x][y] = 1;
}
else if (MAZE[x - 1][y] == 0)
{
di = 4;
Push_Stack(s, x, y, di);
x -= 1;
MAZE[x + 1][y] = 1;
MAZE[x][y] = 1;
}
else
{
int *p, *q, *r;
p = &x;
q = &y;
r = &di;
Pop_Stack(s, p, q, r);
if (x == s->Addr[0].x&&y == s->Addr[0].y)//判定条件为:s->Addr[0]这个栈中的元素存储的为初始出发点的行与列的信息;
{
printf("迷宫无解!\n");
return 0;
} //判定当前坐标与初始值相同则说明又回到起点,无解!
}
answer_maze(s, MAZE, x, y,di);//调用自身,形成递归调用;减小问题的规模;
return 0;
}
int main()
{
Stack *s;
int *q;
int MAZE[11][10] = {
{ 1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,1,0,0,0,1,0,1 },
{ 2,0,0,1,0,0,0,1,0,1 },
{ 3,0,0,0,0,1,1,0,1,1 },
{ 4,0,1,1,1,0,0,1,0,1 },
{ 5,0,0,0,1,0,0,0,0,1 },
{ 6,0,1,0,0,0,1,0,1,1 },
{ 7,0,1,1,1,1,0,0,1,1 },
{ 8,1,1,0,0,0,1,0,1,1 },
{9,1,1,0,0,0,0,0,0,1 },
{10,1,1,1,1,1,1,1,1,1 }
};
q = MAZE;
int rukou_x, rukou_y, dir = 0;
menu();
printf("打印该迷宫:\n");
Print_MAZE(q);
s = Init_Stack();
printf("请输入入口的行标与列标,用空格断开:\n");
scanf_s("%d%d", &rukou_x, &rukou_y);
printf("请输入出口坐标:");
scanf_s("%d%d", &END_X, &END_Y);
Push_Stack(s, rukou_x, rukou_y, dir);
answer_maze(s, MAZE, rukou_x, rukou_y,dir);
return 0;
}
迷宫问题的递归实现方法
于 2018-11-29 22:31:47 首次发布