Java迷宫问题回溯栈,运用栈求解迷宫问题

文章目录

1.题目

2.数据结构

1.用数组对迷宫进行定义

2.试探方向

3.设计栈

4.防止重复到某一点, 以免发生死循环, 将走过的点初始化为 - 1,即maze[x][y] = -1.

5.迷宫算法的求解思想:

3.代码

1.题目

问题描述:设置迷宫为mn的二维数组,起点坐标为(1,1),中点坐标为(m,n),0为通路,1为死路,为防止数组越界将四周设置边界1,即数组变为(m+2)(n+2)数组,迷宫如下…

迷宫

1 1 1 1 1 1 1 1 1 1

1 0 1 1 1 0 1 1 1 1

1 1 0 1 0 1 1 1 1 1

1 0 1 0 0 0 0 0 1 1

1 0 1 1 1 0 1 1 1 1

1 1 0 0 1 1 0 0 0 1

1 0 1 1 0 0 1 1 0 1

1 1 1 1 1 1 1 1 1 1

2.数据结构

1.用数组对迷宫进行定义

#define m 6

#define n 8

int maze[m+2][n+2]

2.试探方向

在正常情况下,每个点有8个方向可以进行试探, 设点坐标(x, y), 即可对该点的坐标进行加减1, 进行位置的变换, 即加上move数组.

例:

0 1 0

1 0 0

1 0 1

现在在中间的位置

typedef struct{

int x, y; //坐标

}item;

item move[8];

void defineMove(item move[8]){

move[0].x = 0, move[0].y = 1; //走右边

move[1].x = 1, move[1].y = 1; //走东北角

move[2].x = 1, move[2].y = 0; //走上面

move[3].x = 1, move[3].y = -1; //走西北角

move[4].x = 0, move[4].y = -1; //走左边

move[5].x = -1, move[5].y = -1; //走西南角

move[6].x = -1, move[6].y = 0; //走下面

move[7].x = -1, move[7].y = 1; //走东南角

}

移动时进行运算, x = x + move[i].x , y = y + move[i].y;

3.设计栈

首先将起点压入栈, 并且从正右方的店进行寻路, 若为0, 即进行压栈, 若不通即进行点的回溯. 寻找其他方向.

点的定义:

typedef struct

{

int x, y, d;

}point;

栈的定义:

typedef struct

{

point data[MAXSIZE];

int top; //栈顶指针

}MazeStack;

4.防止重复到某一点, 以免发生死循环, 将走过的点初始化为 - 1,即maze[x][y] = -1.

5.迷宫算法的求解思想:

(1) 将栈进行初始化

(2)将入口坐标及到达该点的方向(设为-1)入栈

(3)while(栈不为空){

栈顶元素 >= (x,y,d)

出栈

求出下一个要试探的方向d++

whle(还有剩余试探方向){

if(d方向可走){

则{

(x, y, d)入栈

求出新点的坐标 (i,j)

将新点(i,j) 切换为当前点(x, y)

if(x, y) == (m,n) 结束

else 重置d++;

3.代码

/*

*运用顺序栈解决迷宫问题

*/

#include

#include

#define MAXSIZE 100

#define m 6

#define n 8

//对栈中的元素进行定义,d为方向

typedef struct{

int x,y,d;

}point;

//对栈的结构进行定义

typedef struct{

point data[MAXSIZE];

int top;

}MazeStack;

//对移动数组进行定义,方便进行点的移动

typedef struct{

int x,y;

}item;

//将栈设置为空栈

void setNULL(MazeStack *s){

s->top = -1;

}

//判断栈是否为空

bool isEmpty(MazeStack *s){

if(s->top>=0) return false;

else return true;

}

//进栈操作

MazeStack * push(MazeStack *s,point x){

if(s->top>MAXSIZE-1){

printf("栈上溢出!\n");

return s;

}else{

s->top++;

s->data[s->top] = x;

return s;

}

}

//退栈操作

point * pop(MazeStack *s){

if(isEmpty(s)){

printf("栈为空!\n");

return NULL;

}else{

s->top--;

return &(s->data[s->top+1]);

}

}

//取栈顶元素

point * getTop(MazeStack *s){

if(isEmpty(s)){

printf("栈为空!\n");

return NULL;

}else{

return &(s->data[s->top]);

}

}

//对移动的位置进行定义

void defineMove(item xmove[8]){

xmove[0].x = 0,xmove[0].y =1;

xmove[1].x = 1,xmove[1].y =1;

xmove[2].x = 1,xmove[2].y =0;

xmove[3].x = 1,xmove[3].y =-1;

xmove[4].x = 0,xmove[4].y =-1;

xmove[5].x = -1,xmove[5].y =-1;

xmove[6].x = 1,xmove[6].y =0;

xmove[7].x = -1,xmove[7].y =1;

}

//进行所有操作的测试

int main(){

//对迷宫进行定义

int x,y,i,j,d;

//对移动的位置进行定义

item xmove[8];

//定义栈的起始点

point start,*p;

//对栈进行定义

MazeStack *s;

s = (MazeStack*)malloc(sizeof(MazeStack));

setNULL(s);

//对移动的位置进行定义

defineMove(xmove);

//对迷宫进行输入

printf("请输入迷宫:\n");

// for(i = 0;i// for(j = 0;j// scanf("%d",&maze[i][j]);

int maze[m+2][n+2]={{1,1,1,1,1,1,1,1,1,1},

{1,0,1,1,1,0,1,1,1,1},

{1,1,0,1,0,1,1,1,1,1},

{1,0,1,0,0,0,0,0,1,1},

{1,0,1,1,1,0,1,1,1,1},

{1,1,0,0,1,1,0,0,0,1},

{1,0,1,1,0,0,1,1,0,1},

{1,1,1,1,1,1,1,1,1,1}

};

start.x = 1;

start.y = 1;

start.d = -1;

p = (point*)malloc(sizeof(point));

//将起点压入栈

s = push(s,start);

while(!isEmpty(s)){

p = pop(s);

x = p->x;

y = p->y;

d = p->d+1;

while(d<8){

i = xmove[d].x+x;

j = xmove[d].y+y;

if(maze[i][j]==0){ //该方向能走通

p->d = d;

s = push(s,*p);

x = i;

y = j;

maze[x][y] = -1; //置-1

point nw; //将现在的位置记录起来

nw.x = x;

nw.y = y;

nw.d = -1;

s = push(s,nw);

if(x==m&&y==n){

printf("找到出口!\n");

while(!isEmpty(s)){

p = pop(s);

printf("坐标:%d %d 方向:%d\n",p->x,p->y,p->d);

}

return 1;

}else{

break;

}

}else{

d++;

}

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值