基于C语言实现的迷宫求解【栈】【数据结构】
数据结构
·
原理
若当前位置可通,则纳入“当前位置”,并继续朝下一位置探索,即切换“下一位置”为“当前位置”,如此重复以达到出口,若当前位置“不可通”,则应顺着“来向”退回到“前一通道快”,然后朝着除“来向之外”的其他方向继续探索;若该通道快的四周4个方块都 不可通,则应从“当前路径”上删除该通道块。所谓“下一位置”是指“当前位置”四周四个方向(东、西、南、北)上相邻的方块。假设以栈S记录“当前路径”,则栈顶中存放的是“当前路径上最后一个通道块”。因此,“纳入路径”的操作即为“当前位置入栈”;“从当前路径删除前一通道块”即为“出栈”。
具体代码
#include<stdio.h>
#define mazeRowNum 10//迷宫行数
#define mazeColNum 10//迷宫列数
#define MAXSIZE 100//栈大小
//迷宫中的坐标位置
typedef struct{
int x;//行号
int y;//列号
}PosType;
//栈的元素类型
typedef struct{
PosType seat;//坐标位置
int direction;//di=1,2,3,4分别表示东,南,西,北
}SElemType;
typedef struct SqStack{
SElemType data[MAXSIZE];
int top;//指向栈顶元素
}SqStack;
//初始化空栈
void initStack(SqStack &s){
s.top = 0;
}
//判栈空
bool isEmpty(SqStack s){
if(s.top == 0){
printf("是空栈\n");//
return true;
}else{
return false;
}
}
//判栈满
bool isFull(SqStack s){
if(s.top == MAXSIZE){
return true;
}
else{
return false;
}
}
//入栈
void push(SqStack &s, SElemType e){
if(!isFull(s)){
s.data[s.top] = e;
s.top++;
}else
printf("此栈已满,入栈操作失败\n");
}
//出栈
void pop(SqStack &s, SElemType &e){
if(!isEmpty(s)){
e = s.data[s.top-1];
s.top--;
}
else
printf("此栈为空栈,出栈操作失败\n");
}
//'1'表示通道块,'0'表示墙壁
static char maze[mazeRowNum][mazeRowNum] = {
{'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'},
{'0', '1', '1', '0', '1', '1', '1', '0', '1', '0'},
{'0', '1', '1', '0', '1', '1', '1', '0', '1', '0'},
{'0', '1', '1', '1', '1', '0', '0', '1', '1', '0'},
{'0', '1', '0', '0', '0', '1', '1', '1', '1', '0'},
{'0', '1', '1', '1', '0', '1', '1', '1', '1', '0'},
{'0', '1', '0', '1', '1', '1', '0', '1', '1', '0'},
{'0', '1', '0', '0', '0', '1', '0', '0', '1', '0'},
{'0', '0', '1', '1', '1', '1', '1', '1', '1', '0'},
{'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'}
};
PosType start = {1, 1};//设置迷宫起点
PosType end = {7, 7};//设置迷宫终点
void footPrint(PosType curpos){
maze[curpos.x][curpos.y] = 'y';//表示到达
}
void markPrint(PosType curpos){
maze[curpos.x][curpos.y] = 'n';//表示该通道块虽然不是墙壁,但是它仍然不通
}
PosType nextPos(PosType curpos, int direction){
switch(direction){
case 1: curpos.y++;break;//向东走,行号不变,列号加1
case 2: curpos.x++;break;//向南走,行号加1,列号不变
case 3: curpos.y--;break;//向西走,行号不变,列号减1
case 4: curpos.x--;break;//向北走,行号减1,列号不变
}
return curpos;
}
//判断当前位置是否可通,即为'1',而不是'0'、'y'(已走过)、'n'(已走过但不通)
bool pass(PosType curpos){
if(maze[curpos.x][curpos.y] == '1')
return true;
else
return false;
}
//求得一条路径存放在栈中,并返回TRUE,否则返回FALSE
bool mazePath(PosType start, PosType end){
SqStack s;
initStack(s);
PosType curpos = start;//设定当前位置为“入口”位置
do{
if(pass(curpos)){//当前路径可通
footPrint(curpos);//留下标记
SElemType e;
e.seat = curpos;
e.direction = 1;
push(s, e); //加入路径
if(curpos.x == end.x && curpos.y == end.y) //到达出口
return true;
curpos = nextPos(curpos, 1);//下一位置是东边
//curstep++; //探索下一步
}else{//当前位置不能通过,则栈顶元素出栈
SElemType e;
pop(s, e);
//如果弹出的栈顶位置的四周均不可通,则继续往“来路”通道块回退
while(e.direction == 4 && !isEmpty(s)){
markPrint(e.seat);//标记,避免陷入死胡同
pop(s, e);
}
//弹出的栈顶位置尚有其他方向的方块未探索,则切换到下一个方向的方块为当前位置
if(e.direction < 4){
e.direction++;
push(s, e);
curpos = nextPos(e.seat, e.direction);
}
}
}while(!isEmpty(s));//栈不为空则循环继续
return false;
}
//打印迷宫
void printMaze(){
for(int i = 0; i < mazeRowNum; i++){
for(int j = 0; j < mazeColNum; j++){
printf("%c ", maze[i][j]);
}
printf("\n");
}
printf("\n");
}
void main(){
printf("迷宫的初始状态:\n");
printMaze();
if(mazePath(start, end)){
printf("存在通路\n");
printf("迷宫如下:\n");
printMaze();
}else
printf("不存在通路!\n");
}
运行结果

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)