1.简单迷宫(只有一条通路或者是有几条通路(不带环))
SimpleMaze.h
#ifndef AAA
#define AAA
#include<stdio.h>
#include<assert.h>
#define NUMBER 20
#define ROW 6
#define COL 6
typedef int DataType;
//地图
typedef struct Maze
{
int map[ROW][COL];
}Maze;
//坐标
typedef struct Coordinate
{
DataType x;
DataType y;
}Coordinate;
//栈
typedef struct Stack
{
Coordinate a[NUMBER];
int top;
}Stack;
void Cpmap(DataType a[ROW][COL], Maze *q);
void InitStack(Stack *cur);
void WalkMaze(Coordinate entry, Maze *q, Stack *cur);
void WalkMaze2(Coordinate entry, Maze *q, Stack *cur);
void PrintMaze(Maze q);
#endif //AAA
MazeFunc.c
#include"SimpleMaze.h"
//地图
void Cpmap(DataType a[ROW][COL], Maze *q)
{
int i = 0;
int j = 0;
for(i = 0; i < ROW; i++)
{
for(j = 0; j < COL; j++)
{
q->map[i][j] = a[i][j];
}
}
}
//初始化栈
void InitStack(Stack *cur)
{
assert(cur);
cur->top = 0;
}
//入栈
void PushStack(Stack *cur, Coordinate entry)
{
assert(cur);
cur->a[cur->top] = entry;
cur->top++;
}
//出栈
void PopStack(Stack *cur)
{
assert(cur);
cur->top--;
}
//判断栈是否为空
int EmptyStack(Stack *cur)
{
assert(cur);
return 0 == cur->top;
}
//取栈顶的元素
Coordinate TopCellStack(Stack *cur)
{
assert(cur);
if(cur->top != 0)
return cur->a[cur->top-1];
}
//判断该坐标是否是通路
int Passage(Maze *q,int x, int y)
{
//首先判断坐标是否在有效的范围内
if(x < ROW && x >= 0 && y < COL && y >= 0)
{
if(q->map[x][y] == 1)
{
return 1;
}
}
return 0;
}
//判断是否是出口
int ExitMaze(Coordinate ret, Coordinate entry)
{
if((ret.x == 0 || ret.x == ROW-1 || ret.y == 0 || ret.y == COL-1)&& ret.x != entry.x && ret.y != entry.y)
return 1;
return 0;
}
//打印迷宫
void PrintMaze(Maze q)
{
int i = 0;
int j = 0;
for(i = 0; i < ROW; i++)
{
for(j = 0; j < COL; j++)
{
printf("%d ", q.map[i][j]);
}
printf("\n");
}
}
//简单的单通路迷宫
//入口--》走迷宫
//循环下面操作,直到找到出口/站空时退出
// 获取栈顶元素
// 每走一步,标记,判断是否到出口的位置,入栈
// 上:检测tmp的上方是否为通路
//是:向上走--》入栈;continue
// 下:检测tmp的下方是否为通路
//是:向下走--》入栈
// 左:检测tmp的左方是否为通路
//是:向左走--》入栈
// 右:检测tmp的右方是否为通路
//是:向右走--》入栈
// 当前步走错--》回退--》出栈
void WalkMaze(Coordinate entry, Maze *q, Stack *cur)
{
Coordinate ret = entry;
assert(cur && q);
//首先标记入口节点,用2来表示已经走过的节点
q->map[entry.x][entry.y] = 2;
PushStack(cur,entry);
while(!EmptyStack(cur))
{
Coordinate tmp = {0};
ret = TopCellStack(cur);
//到达迷宫的出口
if(ExitMaze(ret, entry))
{
break;
}
tmp = ret;
//上面是通路
if(Passage(q,tmp.x-1, tmp.y))
{
tmp.x -= 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//下面是通路
if(Passage(q,tmp.x+1, tmp.y))
{
tmp.x += 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//左边是通路
if(Passage(q,tmp.x,tmp.y-1))
{
tmp.y -= 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//右边是通路
if(Passage(q, tmp.x, tmp.y+1))
{
tmp.y += 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//如果上下左右都不可以代表此处是一个死胡同,立刻出栈
PopStack(cur);
//用3来表示出栈的地址
q->map[tmp.x][tmp.y] = 3;
}
}
//多条通路的迷宫
//当走到第一条路的出口时,不要立即退出
//而是开始出栈返回,寻找第二条路,
//直到栈为空时停止
void WalkMaze2(Coordinate entry, Maze *q, Stack *cur)
{
Coordinate ret = entry;
assert(cur && q);
//首先标记入口节点,用2来表示已经走过的节点
q->map[entry.x][entry.y] = 2;
PushStack(cur,entry);
while(!EmptyStack(cur))
{
Coordinate tmp = {0};
ret = TopCellStack(cur);
tmp = ret;
//到达迷宫的出口时,先打印一条路径,然后原路返回
if(ExitMaze(ret, entry))
{
PrintMaze(*q);
printf("\n");
q->map[tmp.x][tmp.y] = 3;
}
//上面是通路,向上走
if(Passage(q,tmp.x-1, tmp.y))
{
tmp.x -= 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//下面是通路,向下走
if(Passage(q,tmp.x+1, tmp.y))
{
tmp.x += 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//左边是通路,向左走
if(Passage(q,tmp.x,tmp.y-1))
{
tmp.y -= 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//右边是通路, 向右走
if(Passage(q, tmp.x, tmp.y+1))
{
tmp.y += 1;
PushStack(cur,tmp);
q->map[tmp.x][tmp.y] = 2;
continue;
}
//如果上下左右都不可以代表此处是一个死胡同,代表此时走错了,立刻出栈
PopStack(cur);
//用3来标记走错的路径
q->map[tmp.x][tmp.y] = 3;
}
}
Maze.c
#include"SimpleMaze.h"
void Text()
{
Stack cur = {0};
Coordinate entry;
Maze m = {0};
DataType a[ROW][COL] = {
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1,
0, 1, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1,
0, 1, 0, 0, 0, 0
};
entry.x = 5;
entry.y = 1;
InitStack(&cur);
Cpmap(a, &m);
WalkMaze(entry, &m, &cur);
PrintMaze(m);
}
int main()
{
Text();
return 0;
}
2.带环的迷宫
Maze.h
#ifndef AAA
#define AAA
#include<stdio.h>
#include<assert.h>
#define NUMBER 20
#define ROW 6
#define COL 6
typedef int DataType;
//地图
typedef struct Maze
{
int map[ROW][COL];
}Maze;
//坐标
typedef struct Coordinate
{
DataType x;
DataType y;
}Coordinate;
//栈
typedef struct Stack
{
Coordinate a[NUMBER];
int top;
}Stack;
void StackInit(Stack *ret);
void ArrayInit(DataType a[ROW][COL], Maze *m);
void StackPop(Stack *cur);
int IsPass(Maze* m,Coordinate next,Coordinate ret);
int IsExport( Coordinate next, Coordinate entry);
void StackPush(Stack *cur, Coordinate ret);
void printMaze(Maze m);
void MazeRoute(Maze *m, Coordinate entry, Coordinate ret, Stack *cur, Stack *shortpath);
#endif //AAA
MazeFunc.c
#include"Maze.h"
//栈的初始化
void StackInit(Stack *ret)
{
assert(ret);
ret->top = 0;
}
//初始化地图
void ArrayInit(int a[ROW][COL], Maze *m)
{
int i = 0;
int j = 0;
for(i = 0; i < ROW; i++)
{
for(j = 0; j < COL; j++)
{
m->map[i][j] = a[i][j];
}
}
}
//出栈
void StackPop(Stack *cur)
{
assert(cur);
if((cur)->top == 0)
{
printf("栈空了\n");
return;
}
(cur)->top--;
}
//是否是通路
int IsPass(Maze* m,Coordinate next,Coordinate ret)
{
if(m->map[next.x][next.y] == 1 || m->map[next.x][next.y] > m->map[ret.x][ret.y])
{
return 1;
}
return 0;
}
//判断是否是出口
int IsExport( Coordinate next, Coordinate entry)
{
if(next.x == 0 || next.x == ROW-1 || next.y == 0 || next.y == COL-1)
{
if(next.x != entry.x && next.y != entry.y)
return 1;
}
return 0;
}
//入栈
void StackPush(Stack *cur, Coordinate ret)
{
assert(cur);
cur->a[cur->top] = ret;
cur->top++;
}
//打印
void printMaze(Maze m)
{
int i = 0;
int j = 0;
for(i = 0; i < ROW; i++)
{
for(j = 0; j < COL; j++)
{
printf(" %d ", m.map[i][j]);
}
printf("\n");
}
}
//迷宫路线
void MazeRoute(Maze *m, Coordinate entry, Coordinate ret, Stack *cur, Stack *shortpath)
{
Coordinate next = ret;
if(cur->top == 0)
m->map[entry.x ][entry.y] = 2;
//判断坐标是否合格
if(!(ret.x >= 0 && ret.x < ROW && ret.y >= 0 && ret.y < COL))
{
printf("坐标不合理\n");
return ;
}
//判断是否是出口
if(IsExport(next, entry))
{
int i = 0;
StackPush(cur, ret);
if(shortpath->top == 0 || (shortpath->top > cur->top && shortpath->top))
{
for(i = 0; i < cur->top; i++)
{
shortpath->a[i] = cur->a[i];
}
}
shortpath->top = cur->top;
StackPop(cur);
return ;
}
StackPush(cur, ret);
//上
next = ret;
next.x -= 1;
if(IsPass(m, next, ret))
{
m->map[next.x][next.y] = m->map[ret.x][ret.y]+1;
MazeRoute(m, entry, next, cur, shortpath);
}
//下
next = ret;
next.x += 1;
if(IsPass(m, next, ret))
{
m->map[next.x][next.y] = m->map[ret.x][ret.y]+1;
MazeRoute(m, entry, next, cur, shortpath);
}
//左
next = ret;
next.y -= 1;
if(IsPass(m, next, ret))
{
m->map[next.x][next.y] = m->map[ret.x][ret.y]+1;
MazeRoute(m, entry, next, cur, shortpath);
}
//右
next = ret;
next.y += 1;
if(IsPass(m, next, ret))
{
m->map[next.x][next.y] = m->map[ret.x][ret.y]+1;
MazeRoute(m, entry, next, cur, shortpath);
}
StackPop(cur);
}
Maze.c
#include"Maze.h"
void Text()
{
Stack cur;
Stack shortpath;
Coordinate entry;
Maze m;
DataType a[ROW][COL] = {
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 0, 0,
0, 1, 0, 1, 0, 0,
0, 1, 1, 1, 1, 1,
0, 1, 0, 0, 0, 0
};
entry.x = 5;
entry.y = 1;
StackInit(&cur);
StackInit(&shortpath);
ArrayInit(a, &m);
MazeRoute(&m, entry, entry, &cur, &shortpath);
printMaze(m);
}
int main()
{
Text();
return 0;
}