c语言迷宫问题的求解(栈和递归)

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告

【实验名称】项目一迷宫问题的求解

【实验目的】

1.了解栈的基本操作以及充分理解栈的特点。熟悉掌握栈的基本操作和结构体

的运用。

2.学会用栈或者递归方法解决迷宫问题。

【实验原理】

1.本次实验中,以二维数组maze[row][col]表示迷宫,0表示通路,1表示墙,在构建迷宫时,为了清晰显示,在最外层添加一圈墙。

2.算法的核心思想是利用栈后进先出的特点,对迷宫进行探索,如果此路可行,则将此坐标的信息入栈,如果此路不通,则将此坐标的信息出栈。

3.输入形式:根据控制台的提示,依次输入迷宫的行数、列数,然后输入迷宫,再输入入口和出口坐标。

4.输出形式:由用户选择,由递归、非递归两种求解方式输出一条迷宫通路。以非递归方式会显示一种求解方案,并给出相应的三元组序列和迷宫方阵;以递归方式则会显示出所有的路线。

【实验内容】

1.需求分析

(1)问题描述

以一个m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

要求以递归和非递归两种方式分别输出一条迷宫的通路,以带方向坐标和迷宫图像表示。

(2)基本要求

(1)首先实现一个以链表作存储结构的栈类型,然后编写一个求解迷宫的非递归程序。求得的通路以三元组(i,j,d)的形式输出。其中:(i,j)指示迷宫中的一个坐标,d表示走到下一坐标的方向。如,对于下列数据的迷宫,输出一条通路为:(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),…。

(2)编写递归形式的算法,求得迷宫中所有可能的通路。

(3)以方阵形式输出迷宫及其通路。

2.概要设计

(1)栈的抽象数据类型

ADT Stack{

数据对象:D={ai|ai∈ElemSet, i=1,2, …,n, n≥0}

数据关系:R1={|ai-1,ai∈D, i=1,2, …,n }

约定an端为栈顶,a1端为栈底。

基本操作:

InitStack( &S )

操作结果:构造一个空栈S。

DestroyStack ( &S )

初始条件:栈S已存在。

操作结果:销毁栈S。

ClearStack( &S )

初始条件:栈S已存在。

操作结果:将S清为空栈。

StackEmpty( S )

初始条件:栈S已存在。

操作结果:若S为空栈,则返回TRUE,否则返回FALSE。

StackLength( S )

初始条件:栈S已存在。

操作结果:返回S的数据元素个数,即栈的长度。

GetTop( S, &e )

初始条件:栈S已存在且非空。

操作结果:用e返回S的栈顶元素。

Push( &S, e )

初始条件:栈S已存在。

操作结果:插入元素e为新的栈顶元素。

Pop( &S, &e )

初始条件:栈S已存在且非空。

操作结果:删除S的栈顶元素,并用e返回其值。

}ADT Stack

(2)程序模块

A.主程序模块:

int main()

{

}

B.栈模块:

实现栈抽象数据类型

C.迷宫模块:

实现迷宫抽象数据类型

3.详细设计

(1)类型定义

typedef struct

{

int x;

int y;

}coordinate; //迷宫中坐标类型

typedef struct

{

int x; //x行

int y; //y列

int d; //下一步的位置

}SElemType;//数据类型

typedef struct Stack

{

SElemType elem;

struct Stack *next;

}Stack,*LinkStack; //链栈定义

(2)递归求解算法

void MazePath2(int maze[M][N],int a,int b,coordinate end,int m,int n)

//采用递归的方式进行四个方向的探索

{

maze[a][b]=-1; //起点标记为-1,即一定正确的通路,每次递归便将递归的坐标标记为正确的通路

if(a==end.x&&b==end.y)

{

printf("find a access:\n");

PrintMaze2(maze,m,n); //找到了路径,绘制地图

}

if(maze[a][b+1]==0)

MazePath2(maze,a,b+1,end,m,n); //向右探索

if(maze[a+1][b]==0)

MazePath2(maze,a+1,b,end,m,n); //向下探索

if(maze[a-1][b]==0)

MazePath2(maze,a-1,b,end,m,n); //向上探索

if(maze[a][b-1]==0)

MazePath2(maze,a,b-1,end,m,n); //向左探索

maze[a][b]=0;//如果当前道路不通,则回溯重新探索

}

(3)非递归求解算法

Status MazePath(coordinate start,coordinate end,int maze[M][N]) //迷宫求解函数

{

int row,col,k,a,b,trg=1;//行、宽、新行、新宽、判断标志

int add[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

//行增量和列增量数组方向依次为东西南北

SElemType elem,elem2;//elem用于存储当前的地址信息,elem2用于最后将栈逆置输出

LinkStack S1, S2; //S1用于存放迷宫路径,S2用于逆置

InitStack(S1);

InitStack(S2); //栈的初始化

maze[start.x][start.y]=2; //标记初始位置

elem.x=start.x;

elem.y=start.y;

elem.d=-1;

Push(S1,elem); //进行第一次入栈,代表从起点出发

while(!StackEmpty(S1)) //栈不为空有可行路径

{

Pop(S1,elem); //出栈,获取当前坐标及方向信息

row=elem.x;

col=elem.y;

k=elem.d+1; //下一个方向

while(k<4) //试探东南西北各个方向(0-东,1-南,2-西,3北)

{

a=row+add[k][0]; //新的行坐标

b=col+add[k][1]; //新的列坐标

if(a==end.x && b==end.y && maze[a][b]==0) //找到出口

{

elem.x=row;

elem.y=col;

elem.d=k; //4代表找到了出口

Push(S1,elem);

elem.x=a;

elem.y=b;

elem.d=4;

相关文档
最新文档