所需知识
递归
结构体
❀思路分析
如图为一个简单的迷宫地图
简答理解为,数字1代表通路,数字0代表障碍物。
1.怎样创建迷宫地图的信息
创建一个结构体,内放二维数组来保存迷宫地图的坐标
/建立一个地图
typedef int DataType;
//迷宫
typedef struct Map
{
DataType map[ROW][COL];
}Map;
2.怎样探路
创建一个结构体,用来保存地图中的位置(x,y)坐标,从入口开始,分别上下左右检测周边坐标元素,如果元素值为1,代表探测到了通路,则改变坐标到这一位置,以此类推。
//位置
typedef struct Position
{
int x;
int y;
}Point;
3.上下左右探路的时候怎么避免不走已经走过的路
将已经走过的路做一个标记,将值1改为2
4.遇到岔路口怎么办
走错路,探到了死路怎么办,如图
如果探路的优先级是,左侧和下侧在前,坐标很有可能走到该位置,此时坐标为(4,2)四面都不可走,此时说明之前某一个坐标的方向很有可能走错了,那我们就需要回到之前走错的这个路口(坐标)怎么回到前一坐标呢?定义一个栈,在开始让坐标移动的时候就用这个栈来保存走过的位置的坐标。在发现走入死胡同时,从栈中取出栈顶元素,即为上一步的位置,再次寻找其他出路
具体操作实现
#define __MAZE_H__
#ifdef __MAZE_H__
#define ROW 6 //行,纵坐标
#define COL 6 //列,横坐标
#include <stdio.h> //打印
#include <stdlib.h>
#include <assert.h>
//建立一个地图
typedef int DataType;
//迷宫
typedef struct Map
{
DataType map[ROW][COL];
}Map;
//位置
typedef struct Position
{
int x;
int y;
}Point;
//栈
typedef struct Stack
{
Point Sta[40];
int top;//栈顶,有效数的后一位坐标
}Stack;
//初始化栈
void InitStack(Stack * s);
//入栈
void PushStack(Stack * s, DataType d);
//出栈
void PopStack(Stack *s);
//取栈顶位置
Point StackTop(Stack * s);
//打印栈
void PrintStack(Stack * s);
//测试栈
void testStack(Stack *s);
//清空栈
void EmptyStack(Stack *s);
//初始化迷宫
void InitMaze(Map * maze);
//打印迷宫
void PrintMap(Map * maze);
//通过迷宫和入口寻找出路
void FindExit(Map * maze, Point entry);
//显示路线
void Path(Map * maze, Stack * s);
#endif //__MAZE_H__
//maze.c
#include "Maze.h"
//初始化栈
void InitStack(Stack * s)
{
assert(s);
s->top = 0;
}
//入栈
void PushStack(Stack * s,int x,int y)
{
assert(s);
if (40 == s->top )
return;
s->Sta[s->top].x = x;
s->Sta[s->top].y = y;
s->top++;
}
//出栈
void PopStack(Stack *s)
{
assert(s);
s->top--;
}
//取栈顶元素
Point StackTop(Stack * s)
{
return (s->Sta [s->top-1]);
}
//打印栈
void PrintStack(Stack * s)
{
for (int i = 0; i < s->top; i++)
{
printf(" x=%d ,y = %d \n", s->Sta[i].x,s->Sta[i].y);
}
printf("\n");
}
//清空栈
void EmptyStack(Stack * s)
{
s->top = 0;
}
//测试栈
void testStack(Stack * s)
{
printf("测试栈\n");
InitStack(s);
printf("入栈1,1、2,1、,3,3、4,3、5,7\n");
PushStack(s, 1,1);
PushStack(s, 2,1);
PushStack(s, 3,3);
PushStack(s, 4,3);
PushStack(s, 5,7);
PrintStack(s);
PopStack(s);
printf("出栈一次\n");
PrintStack(s);
EmptyStack(s);
printf("清空栈\n");
PrintStack(s);
}
void InitMaze(Map * maze)
{
int col = 0, row = 0;
if (maze == NULL)//非法传参,按理这里为Map类型的指针
{
return;
}
//0 0 0 0 0 0
//1 1 1 1 0 0
//0 0 0 1 0 0
//0 1 1 1 1 1
//0 0 1 0 0 0
//0 0 0 0 0 0
//初始化一个数组
DataType arr[ROW][COL] = {
{ 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 0, 0 },
{ 0, 0, 0, 1, 0, 0 },
{ 0, 1, 1, 1, 1, 1 },
{ 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
//把该数组的值传递给迷宫
for (row = 0; row < ROW; row++)
{
for (col = 0; col < COL; col++)
{
maze->map[row][col] = arr[row][col];
}
}
}
void PrintMap(Map *maze)
{
int col = 0, row = 0;
printf("迷宫地图为\n-------------------\n");
for (row = 0; row < ROW; row++)
{
for (col = 0; col < COL; col++)
{
printf(" %d ",maze->map[row][col]);
}
printf("\n");
}
}
//检测当前节点是否有通路,优先次序为上左右下,入栈
int Pass(Map * maze, int x,int y)
{
if (x >= ROW || y >= COL)
{
perror("error\n");
return 0;
}
if (maze->map[x][y] == 1)
return 1;
return 0;
}
//检测是否走出迷宫
int YesPass(Map * maze, Point pos)
{
if (pos.x == 0 || pos.y == 0 || pos.x == ROW - 1 || pos.y == COL - 1)
return 1;
return 0;
}
//通过迷宫地图和入口找出口
void FindExit(Map * maze, Point entry,Stack *s)
{
Point cur = entry;
Point pre = cur;
//探路走起来
do
{
if (Pass(maze,cur.x -1,cur.y))
{
PushStack(s,cur.x,cur.y);//入栈
maze->map[cur.x][cur.y] = 2;
pre = cur;
cur.x = cur.x - 1;
continue;
}
if (Pass(maze,cur.x,cur.y-1))
{
PushStack(s, cur.x,cur.y);//入栈
maze->map[cur.x][cur.y] = 2;
pre = cur;
cur.y = cur.y - 1;
continue;
}
if (Pass(maze,cur.x,cur.y+1))
{
PushStack(s,cur.x,cur.y);//入栈
maze->map[cur.x][cur.y] = 2;
pre = cur;
cur.y = cur.y + 1;
continue;
}
if (Pass(maze,cur.x+1,cur.y))
{
PushStack(s,cur.x,cur.y);//入栈
maze->map[cur.x][cur.y] = 2;
pre = cur;
cur.x = cur.x + 1;
continue;
}
//四个方向都不通,回退
maze->map[cur.x][cur.y] = 3;
cur = StackTop(s);
PopStack;
} while (!YesPass(maze, cur) || ((entry.x == cur.y) && (entry.y == cur.y)));
//出口单独最后入栈
PushStack(s, cur.x, cur.y);
}
//显示路线
void Path(Map * maze,Stack * s)
{
while (s->top)
{
maze->map[StackTop(s).x][StackTop(s).y] = 8;
PopStack(s);
}
printf("---------------------\n");
for (int row = 0; row < ROW; row++)
{
for (int col = 0; col < COL; col++)
{
if (maze->map[row][col] != 8)
maze->map[row][col] = 0;
printf(" %d ", maze->map[row][col]);
}
printf("\n");
}
}
#include "Maze.h"
int main()
{
Map maze;//创建地图
Stack s;//创建保存路径的栈
Point e;//给入口坐标
e.x = 3;
e.y = 5;
testStack(&s);//测试栈的各个函数
InitStack(&s);
InitMaze(&maze);
PrintMap(&maze);
FindExit(&maze, e,&s);
PrintStack(&s);
PrintMap(&maze);
//显示路线
Path(&maze,&s);
system("pause");
return 0;
}