原理:通过栈的原理 先进后出 后进先出
通过对迷宫的不断查找
找到最好的
//图的搜索策略解决迷宫问题
#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;
}