数据结构 study 10:迷宫求解
page60 ,page50
题目解析:
构造一个如图下面的迷宫
0表示墙
1表示可以走的路
把上面的问题 简单的解析一下
去掉构造迷宫的过程,不用手动输入,
假设是有一个现成的迷宫,这个迷宫固定不变。
这个迷宫的大小是 10x10
这个迷宫的墙用0表示
这个迷宫的路用1表示
有一个 下面的迷宫
入口坐标是1,1 ,出口坐标是8,8
那么精灵 从1,1 出发,上北下南,左西右东,按照方向优先级 东南西北,这个方向走。
小精灵 从起点(1,1)开始,按照方向,东南西北,这个方向依次向前走。
每走一格,就将走通的格子,标记一下步数。
遇到走不通的格子,标记为 -1.
精灵的动作,选择方向,走一格子。
是否走通。
如果通,标记格子,放入栈中。
继续选择方向,走下一格子。
如果没有走通,就换向,走下一格子。
如果4个方向都没有走通,标记这个格子为-1
退回上一个格子,选择方向,走一个格子。
看上面的描述:
程序需要,定义一下坐标结构体。
typedef struct /* 迷宫坐标位置类型 /
{
int x; / 行值 /
int y; / 列值 */
}PosType;
还需要定义一下 精灵的结构体:
typedef struct
{
PosType pos;
int direct ; //东南西北
}Role;
PosType direc[4]={{0,1},{1,0},{0,-1},{-1,0}}; /* {行增量,列增量} */
迷宫的格子,0表示墙,1,表示路,大于1,表示步数。
-1 表示虽然是路,但是 这个路,已经走过了,走不通。
迷宫需要提供 如下的功能。
当前坐标的下一个坐标是啥?
PosType NextPos(PosType c,int di)
{
}
对迷宫的格子,进行标记,标记这个格子走不通
void MarkPrint(PosType b)
{
}
走过的迷宫的格子 是第几步
void FootPrint(PosType a)
{
}
迷宫的这个格子 是否 可以通过
Status Pass(PosType b)
{
}
演示 代码如下:
/* c1.h (程序名) */
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include <sys/io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<pthread.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
int curstep=1; /* 当前足迹,初值为1 */
typedef enum {RIGHT, DOWN, LEFT,UP} direct_t;
/* algo3-5.c 利用栈求解迷宫问题(只输出一个解,算法3.3) */
typedef struct /* 迷宫坐标位置类型 */
{
int x; /* 行值 */
int y; /* 列值 */
}PosType;
typedef struct
{
PosType pos ;
direct_t direct ; // 0,1,2,3 东南西北 顺时针
}Role ;
#define MAXLENGTH 10 /* 设迷宫的最大行列为10 */
typedef int MazeType[MAXLENGTH][MAXLENGTH]; /* 迷宫数组[行][列] */
/* 全局变量 */
/* 迷宫数组 */
MazeType m =
{
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
};
void Print(int x,int y)
{ /* 输出迷宫的解 */
int i,j;
for(i=0;i<x;i++)
{
for(j=0;j<y;j++)
printf("%3d",m[i][j]);
printf("\n");
}
}
void Print_Path(void)
{ /* 输出迷宫的解 */
int i=0,j=0;
printf("\n------------curstep = %d----------\n",curstep);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
printf("%3d",m[i][j]);
printf("\n");
}
printf("\n");
}
Boolean Pass(PosType b)
{
if(m[b.y][b.x] == 1){
return TRUE;
}
return FALSE;
}
PosType NextPos(PosType c,int di)
{
//PosType direct[4]={{0,1},{1,0},{0,-1},{-1,0}}; /* {行增量,列增量} */
PosType direct[4]={{1,0},{0,1},{-1,0},{0,-1}}; /* {行增量,列增量} */
c.x += direct[di].x;
c.y += direct[di].y;
return c;
}
void MarkPrint(PosType b)
{ /* 使迷宫m的b点的序号变为-1(不能通过的路径) */
m[b.y][b.x]=-1;
}
void FootPrint(PosType pos,int cur_step)
{ /* 使迷宫m的a点的序号变为足迹(curstep) */
m[pos.y][pos.x]=cur_step;
}
/* c3-1.h 栈的顺序存储表示 */
#define STACK_INIT_SIZE 100 /* 存储空间初始分配量 */
#define STACKINCREMENT 2 /* 存储空间分配增量 */
typedef Role ElemType ;
typedef struct sqStack
{
ElemType *top ;
ElemType *base ;
int stack_size ;
}sqStack ;
Status init_stack(sqStack *S)
{
S->base = (ElemType *)malloc(sizeof(ElemType)*STACK_INIT_SIZE);
S->top = S->base ;
S->stack_size = STACK_INIT_SIZE ;
return OK;
}
Status push_stack(sqStack *S, ElemType e)
{
if(S->top - S->base < S->stack_size){
*(S->top++) = e ;
return OK ;
}
return ERROR;
}
Status pop_stack(sqStack *S, ElemType *e)
{
if(!empty_stack(S)){
*e = *(--(S->top));
return OK;
}
return ERROR;
}
Boolean empty_stack(sqStack *S)
{
if(S->top == S->base){
return TRUE;
}
return FALSE ;
}
Status clear_stack(sqStack *S)
{
(*S).top=(*S).base;
return OK;
}
Status destroy_stack(sqStack *S)
{
free((*S).base);
(*S).base=NULL;
(*S).top=NULL;
(*S).stack_size=0;
return OK;
}
void visit(ElemType e)
{
//fputc(e,fp);
}
Status traverse_stack(sqStack *S, void (*visit)(ElemType))
{
ElemType *pt ;
pt = S->base ;
while(pt < S->top ){
visit(*(pt++));
}
}
Status MazePath(PosType start,PosType end)
{
Role role ;
sqStack S;
init_stack(&S);
PosType nextPos ;
role.pos = start ;
role.direct = RIGHT;
curstep = 1;
while(1){
Print_Path();
nextPos = NextPos(role.pos, role.direct);
if(Pass(nextPos)){
push_stack(&S,role);
FootPrint(role.pos, curstep);
curstep++ ;
if(nextPos.x == end.x && nextPos.y == end.y){
break ;
}
role.pos = nextPos;
role.direct = RIGHT;
}else{
/*下一步不是通的*/
if(role.direct ==3){
/*4个方向都试过了,退回上一个格子*/
MarkPrint(role.pos);
curstep-- ;
if(!empty_stack(&S)){
pop_stack(&S,&role);
}else{
return ERROR;
}
}else{
/*换个方向*/
role.direct++;
}
}
}
return OK;
}
int main()
{
PosType begin,end;
int x;
int y;
x = 10;
y = 10;
printf("迷宫的布局为:\n");
Print(x,y);
begin.x = 1;
begin.y = 1;
end.x = 8;
end.y = 8;
if(MazePath(begin,end)) /* 求得一条通路 */
{
printf("此迷宫从入口到出口的一条路径如下:\n");
Print(x,y); /* 输出此通路 */
}
else{
printf("此迷宫没有从入口到出口的路径\n");
}
}
严蔚敏 数据结构 和 高一凡 数据结构解析 结合学习,搭配使用,效果更佳