栈方法 做迷宫

原理:通过栈的原理 先进后出 后进先出
通过对迷宫的不断查找
找到最好的
//图的搜索策略解决迷宫问题
#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OVERFLOW 0
#define ERROR 0
#define OK 1

#define M 10 //迷宫的列数
#define N 10 //迷宫的行数

typedef struct{
int pi;//父节点的行号
int pj;//父节点的列号
int i;//当前节点的行号
int j;//当前节点的列号
}SElemType; //定义栈元素类型

typedef struct{
int i;//当前节点的行号
int j;//当前节点的列号
}Node; //定义节点元素类型

typedef struct
{
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;

typedef int Status;

static int MM[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//迷宫

static int F[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//足迹;

Status InitStack(SqStack &s)
{
//构造一个空栈S
s.base=(SElemType )malloc(STACK_INIT_SIZEsizeof(SElemType));
if(!s.base) //存储分配失败
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack

Status GetTop(SqStack s,SElemType &e)
{
//若栈不空,则用e返回s的栈顶元素,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*(s.top-1);
return OK;
}//GetTop

Status Push(SqStack &s,SElemType e)
{
//插入元素e为新的栈顶元素
if(s.top-s.base>=s.stacksize) //栈满,追加存储空间
{
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW); //存储分配失败
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
return OK;
}//Push

Status Pop(SqStack &s,SElemType &e)
{
//若栈不空,则删除s的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*–s.top;
return OK;
}//Pop

Status empty(SqStack s)
{
if(s.top-s.base==0)//判断是否为空,此栈为空两指针大小相等,否则不为空
return 1;
else
return 0;
}//empty

//取下一个节点
Status GetNextnode(Node e1,int n,Node &e2){
//参数e1表示当前节点,n表示方向n=1,2,…,8,考虑了8个方向
//若下一个节点存在,则函数返回OK,下一个节点的值存放在e2中;
//方向的约定是正下方为1,右下方2,正右方为3,右上方4,正上方为5,左上方6,正左方为7,左下方8
switch(n){
case 1://正下方
{
e2.i=e1.i+1;
e2.j=e1.j;
break;
}
case 2://右下方
{
e2.i=e1.i+1;
e2.j=e1.j+1;
break;
}
case 3://正右方
{
e2.i=e1.i;
e2.j=e1.j+1;
break;
}
case 4://右上方
{
e2.i=e1.i-1;
e2.j=e1.j+1;
break;
}
case 5://正上方
{
e2.i=e1.i-1;
e2.j=e1.j;
break;
}
case 6://左上方
{
e2.i=e1.i-1;
e2.j=e1.j-1;
break;
}
case 7://正左方
{
e2.i=e1.i;
e2.j=e1.j-1;
break;
}
case 8://左下方
{
e2.i=e1.i+1;
e2.j=e1.j-1;
break;
}
default: return 0;
}
printf("%d,%d,n=%d\n",e2.i,e2.j,n);
return 1;
}

int compassable(Node e)
{
printf("%d,%d\n",e.i,e.j);
return F[e.i][e.j];
}

void SearchPath()
{
SqStack s;
Node e1,e2,end;
SElemType se,se1,p[100];
int i=0,di,j;

InitStack(s);//初始化栈

//指定入口
e1.i=1;e1.j=1;
//指定出口
end.i=8;end.j=8;
//构造栈元素
se.pi=0;se.pj=0;se.i=e1.i;se.j=e1.j;
Push(s,se);
printf("****************\n");
while(!empty(s)){
Pop(s,se);
//将se插入的closed表中
p[i].i=se.i;
p[i].j=se.j;
p[i].pi=se.pi;
p[i].pj=se.pj;
i++;
printf("++++++++++++++%d++++++\n",i);

//判断是否达到终点,如果到达终点则跳出while循环.
if(se.i==end.i&&se.j==end.j) {printf("\nThe path hava found!\n");break;}
//没有到达终点则将se的下一代可行的节点入栈

e1.i=se.i;e1.j=se.j;
for(di=1;di<=8;di++)//考虑八个方向
{
   GetNextnode(e1,di,e2);
   printf("%d,%d,di=%d\n",e1.i,e1.j,di);
   if(compassable(e2))
   {
       //构造栈元素
       se1.i=e2.i;
       se1.j=e2.j;
       se1.pj=se.j;
       se1.pi=se.i;
       //下一代可通的节点入栈
       Push(s,se1);
       //留下足迹
       F[e2.i][e2.j]=0;
       printf("_____________________\n");
   }//endif
}//endfor  

}//endwhile
for(j=0;j<i;j++)
printf(“i=%d,j=%d,pi=%d,pj=%d\n”,p[j].i,p[j].j,p[j].pi,p[j].pj);
}

main()
{

SearchPath();
return 1;
}

//图的搜索策略解决迷宫问题
#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OVERFLOW 0
#define ERROR 0
#define OK 1

#define M 10 //迷宫的列数
#define N 10 //迷宫的行数

typedef struct{
int pi;//父节点的行号
int pj;//父节点的列号
int i;//当前节点的行号
int j;//当前节点的列号
}SElemType; //定义栈元素类型

typedef struct{
int i;//当前节点的行号
int j;//当前节点的列号
}Node; //定义节点元素类型

typedef struct
{
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;

typedef int Status;

static int MM[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//迷宫

static int F[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//足迹;

Status InitStack(SqStack &s)
{
//构造一个空栈S
s.base=(SElemType )malloc(STACK_INIT_SIZEsizeof(SElemType));
if(!s.base) //存储分配失败
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack

Status GetTop(SqStack s,SElemType &e)
{
//若栈不空,则用e返回s的栈顶元素,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*(s.top-1);
return OK;
}//GetTop

Status Push(SqStack &s,SElemType e)
{
//插入元素e为新的栈顶元素
if(s.top-s.base>=s.stacksize) //栈满,追加存储空间
{
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW); //存储分配失败
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
return OK;
}//Push

Status Pop(SqStack &s,SElemType &e)
{
//若栈不空,则删除s的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*–s.top;
return OK;
}//Pop

Status empty(SqStack s)
{
if(s.top-s.base==0)//判断是否为空,此栈为空两指针大小相等,否则不为空
return 1;
else
return 0;
}//empty

//取下一个节点
Status GetNextnode(Node e1,int n,Node &e2){
//参数e1表示当前节点,n表示方向n=1,2,…,8,考虑了8个方向
//若下一个节点存在,则函数返回OK,下一个节点的值存放在e2中;
//方向的约定是正下方为1,右下方2,正右方为3,右上方4,正上方为5,左上方6,正左方为7,左下方8
switch(n){
case 1://正下方
{
e2.i=e1.i+1;
e2.j=e1.j;
break;
}
case 2://右下方
{
e2.i=e1.i+1;
e2.j=e1.j+1;
break;
}
case 3://正右方
{
e2.i=e1.i;
e2.j=e1.j+1;
break;
}
case 4://右上方
{
e2.i=e1.i-1;
e2.j=e1.j+1;
break;
}
case 5://正上方
{
e2.i=e1.i-1;
e2.j=e1.j;
break;
}
case 6://左上方
{
e2.i=e1.i-1;
e2.j=e1.j-1;
break;
}
case 7://正左方
{
e2.i=e1.i;
e2.j=e1.j-1;
break;
}
case 8://左下方
{
e2.i=e1.i+1;
e2.j=e1.j-1;
break;
}
default: return 0;
}
printf("%d,%d,n=%d\n",e2.i,e2.j,n);
return 1;
}

int compassable(Node e)
{
printf("%d,%d\n",e.i,e.j);
return F[e.i][e.j];
}

void SearchPath()
{
SqStack s;
Node e1,e2,end;
SElemType se,se1,p[100];
int i=0,di,j;

InitStack(s);//初始化栈

//指定入口
e1.i=1;e1.j=1;
//指定出口
end.i=8;end.j=8;
//构造栈元素
se.pi=0;se.pj=0;se.i=e1.i;se.j=e1.j;
Push(s,se);
printf("****************\n");
while(!empty(s)){
Pop(s,se);
//将se插入的closed表中
p[i].i=se.i;
p[i].j=se.j;
p[i].pi=se.pi;
p[i].pj=se.pj;
i++;
printf("++++++++++++++%d++++++\n",i);

//判断是否达到终点,如果到达终点则跳出while循环.
if(se.i==end.i&&se.j==end.j) {printf("\nThe path hava found!\n");break;}
//没有到达终点则将se的下一代可行的节点入栈

e1.i=se.i;e1.j=se.j;
for(di=1;di<=8;di++)//考虑八个方向
{
   GetNextnode(e1,di,e2);
   printf("%d,%d,di=%d\n",e1.i,e1.j,di);
   if(compassable(e2))
   {
       //构造栈元素
       se1.i=e2.i;
       se1.j=e2.j;
       se1.pj=se.j;
       se1.pi=se.i;
       //下一代可通的节点入栈
       Push(s,se1);
       //留下足迹
       F[e2.i][e2.j]=0;
       printf("_____________________\n");
   }//endif
}//endfor  

}//endwhile
for(j=0;j<i;j++)
printf(“i=%d,j=%d,pi=%d,pj=%d\n”,p[j].i,p[j].j,p[j].pi,p[j].pj);
}

main()
{

SearchPath();
return 1;
}

//图的搜索策略解决迷宫问题
#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define OVERFLOW 0
#define ERROR 0
#define OK 1

#define M 10 //迷宫的列数
#define N 10 //迷宫的行数

typedef struct{
int pi;//父节点的行号
int pj;//父节点的列号
int i;//当前节点的行号
int j;//当前节点的列号
}SElemType; //定义栈元素类型

typedef struct{
int i;//当前节点的行号
int j;//当前节点的列号
}Node; //定义节点元素类型

typedef struct
{
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;

typedef int Status;

static int MM[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//迷宫

static int F[10][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0},
{0,1,1,1,1,0,0,0,0,0},
{0,1,0,0,1,0,0,0,0,0},
{0,1,0,0,1,0,1,1,1,0},
{0,1,0,1,1,1,1,0,1,0},
{0,1,0,0,0,0,0,0,1,0},
{0,1,1,1,1,1,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0}};//足迹;

Status InitStack(SqStack &s)
{
//构造一个空栈S
s.base=(SElemType )malloc(STACK_INIT_SIZEsizeof(SElemType));
if(!s.base) //存储分配失败
exit(OVERFLOW);
s.top=s.base;
s.stacksize=STACK_INIT_SIZE;
return OK;
}//InitStack

Status GetTop(SqStack s,SElemType &e)
{
//若栈不空,则用e返回s的栈顶元素,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*(s.top-1);
return OK;
}//GetTop

Status Push(SqStack &s,SElemType e)
{
//插入元素e为新的栈顶元素
if(s.top-s.base>=s.stacksize) //栈满,追加存储空间
{
s.base=(SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!s.base) exit(OVERFLOW); //存储分配失败
s.top=s.base+s.stacksize;
s.stacksize+=STACKINCREMENT;
}
*s.top++=e;
return OK;
}//Push

Status Pop(SqStack &s,SElemType &e)
{
//若栈不空,则删除s的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
if(s.top==s.base) return ERROR;
e=*–s.top;
return OK;
}//Pop

Status empty(SqStack s)
{
if(s.top-s.base==0)//判断是否为空,此栈为空两指针大小相等,否则不为空
return 1;
else
return 0;
}//empty

//取下一个节点
Status GetNextnode(Node e1,int n,Node &e2){
//参数e1表示当前节点,n表示方向n=1,2,…,8,考虑了8个方向
//若下一个节点存在,则函数返回OK,下一个节点的值存放在e2中;
//方向的约定是正下方为1,右下方2,正右方为3,右上方4,正上方为5,左上方6,正左方为7,左下方8
switch(n){
case 1://正下方
{
e2.i=e1.i+1;
e2.j=e1.j;
break;
}
case 2://右下方
{
e2.i=e1.i+1;
e2.j=e1.j+1;
break;
}
case 3://正右方
{
e2.i=e1.i;
e2.j=e1.j+1;
break;
}
case 4://右上方
{
e2.i=e1.i-1;
e2.j=e1.j+1;
break;
}
case 5://正上方
{
e2.i=e1.i-1;
e2.j=e1.j;
break;
}
case 6://左上方
{
e2.i=e1.i-1;
e2.j=e1.j-1;
break;
}
case 7://正左方
{
e2.i=e1.i;
e2.j=e1.j-1;
break;
}
case 8://左下方
{
e2.i=e1.i+1;
e2.j=e1.j-1;
break;
}
default: return 0;
}
printf("%d,%d,n=%d\n",e2.i,e2.j,n);
return 1;
}

int compassable(Node e)
{
printf("%d,%d\n",e.i,e.j);
return F[e.i][e.j];
}

void SearchPath()
{
SqStack s;
Node e1,e2,end;
SElemType se,se1,p[100];
int i=0,di,j;

InitStack(s);//初始化栈

//指定入口
e1.i=1;e1.j=1;
//指定出口
end.i=8;end.j=8;
//构造栈元素
se.pi=0;se.pj=0;se.i=e1.i;se.j=e1.j;
Push(s,se);
printf("****************\n");
while(!empty(s)){
Pop(s,se);
//将se插入的closed表中
p[i].i=se.i;
p[i].j=se.j;
p[i].pi=se.pi;
p[i].pj=se.pj;
i++;
printf("++++++++++++++%d++++++\n",i);

//判断是否达到终点,如果到达终点则跳出while循环.
if(se.i==end.i&&se.j==end.j) {printf("\nThe path hava found!\n");break;}
//没有到达终点则将se的下一代可行的节点入栈

e1.i=se.i;e1.j=se.j;
for(di=1;di<=8;di++)//考虑八个方向
{
   GetNextnode(e1,di,e2);
   printf("%d,%d,di=%d\n",e1.i,e1.j,di);
   if(compassable(e2))
   {
       //构造栈元素
       se1.i=e2.i;
       se1.j=e2.j;
       se1.pj=se.j;
       se1.pi=se.i;
       //下一代可通的节点入栈
       Push(s,se1);
       //留下足迹
       F[e2.i][e2.j]=0;
       printf("_____________________\n");
   }//endif
}//endfor  

}//endwhile
for(j=0;j<i;j++)
printf(“i=%d,j=%d,pi=%d,pj=%d\n”,p[j].i,p[j].j,p[j].pi,p[j].pj);
}

main()
{

SearchPath();
return 1;
}

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值