数据结构实验报告
实习1 栈和队列及其应用
题目:迷宫问题
班级:1403011班 姓名:付尧 学号:[1**********] 完成日期:2015.11.25
一.需求分析
1.以二维数组maze[m][n]表示迷宫,再为周围加一圈障碍。数组以元素值为0表示通路,1表示障碍。
2.用户以文件的形式输入迷宫的数据:文件中第一行的数据为迷宫的行数m和列数n;从第二行到第m+1行(每行n个数)为迷宫值。
3.迷宫的入口位置默认为(1,1),出口位置默认为(m,n)。
4.程序执行的命令包括:
(1)创建迷宫;(2)求解迷宫;(3)输出迷宫的解;(4)结束。
5.测试数据
测试数据见原题,已存储在maze.txt文件中。输出内容为:(1,1,1),(2,1,1),(3,1,1),(4,1,1),(5,1,1),(6,1,1),(5,1,2),(5,2,2),(5,3,1),(6,3,2),(6,4,2),(6,5,3),(5,5,2),(5,6,2),(5,7,1),(6,7,1),(7,7,1),(8,7,1),(9,7,2),(9,8,0)
二.概要设计
为了实现程序上述功能,应以队列为存储结构。
1. 基本操作:
void GoMaze( )
操作结果:求解迷宫,并输出一条通路。
2. 本程序包含三个模块:
(1)构建迷宫及主程序模块;
(3)执行迷宫求解模块;
三.详细设计
1.元素类型,结点类型和指针类型:
typedef struct {
int ord;
int x,y;
int di;
int pre;
}elem;
elem **maze;
int i,j,m,n,a,b;
int c=0;
queue s;
6.每个模块的分析:
(1)构建迷宫及主程序模块:
int main(){
FILE *mazefile;
mazefile = fopen("maze.txt","r");
fscanf(mazefile,"%d %d\n",&a,&b); //读入行数和列数
m=a+2;
n=b+2; //在周围添加一圈障碍后的行数和列数
maze = new elem*[m];
for (i=0;i
maze[i] = new elem [n];
for (i=0;i
for (int j=0;j
char ch;
maze[i][j].x=i;
maze[i][j].y=j;
maze[i][j].pre=0;
maze[i][j].di=0;
if(i==0||j==0||i==m-1||j==n-1)
maze[i][j].ord=1;
else{
fscanf(mazefile,"%c",&ch);
maze[i][j].ord=(ch-'0');
}
}
fscanf(mazefile,"\n");
}
GoMaze(1,1); //执行迷宫求解函数
printf("(%d,%d,0)",m-2,n-2); //输出终点(迷宫求解函数只输出除终点外的路径)
return 0;
}
(2)执行迷宫求解模块:
void GoMaze(int x,int y){
if(x==(m-2)&&y==(n-2)) //创建计数器,保证递归终止条件
c++;
if(x+1
if(maze[x][y].pre==3) //弹出遇到死路的元素
s.pop();
else{
maze[x+1][y].ord=1;
maze[x][y].di
=1; //设立方向标志
maze[x+1][y].pre=1; //为此元素做标记,防止再次访问
s.push(maze[x][y]); //元素入队列
GoMaze(x+1,y); //进入递归
maze[x+1][y].ord=0; //将元素恢复
}
}
if(y+1
if(maze[x][y].pre==4)
s.pop();
else{
maze[x][y+1].ord=1;
maze[x][y].di=2;
maze[x][y+1].pre=2;
s.push(maze[x][y]);
GoMaze(x,y+1);
maze[x][y+1].ord=0;
}
}
if(x-1>=0&&maze[x-1][y].ord==0&&c==0){
if(maze[x][y].pre==1)
s.pop();
else{
maze[x-1][y].ord=1;
maze[x][y].di=3;
maze[x-1][y].ord=3;
s.push(maze[x][y]);
GoMaze(x-1,y);
maze[x-1][y].ord=0;
}
}
if(y-1>=0&&maze[x][y-1].ord==0&&c==0){
if(maze[x][y].pre==2)
s.pop();
else{
maze[x][y-1].ord=1;
maze[x][y].di=4;
maze[x][y-1].pre=4;
s.push(maze[x][y]);
GoMaze(x,y-1);
maze[x][y-1].ord=0;
}
}
while(!s.empty()){ //输出队列内已储存的通路
elem t=s.front();
printf("(%d,%d,%d),",t.x,t.y,t.di);
s.pop(); //弹出元素
}
}
四.调试分析
(1)设计过程中对递归结束的条件感到疑惑,经过考虑,设立了一个计数器c,解决问题。
(2)程序采用c++中queue函数,减少了c语言中构建队列的冗长代码,方便快捷。
(3)这道题第一眼看觉得仅仅是个递归的简单应用,但实际操作还是有很多需要考虑的地方,比如如何终止递归,防止其他函数再次执行函数。
五.用户使用说明
(1)本程序的运行环境为VS2010。
(2)进入演示程序后即直接输出结果。
六.测试结果
当正确添加文件,就可以得出结果(1,1,1),(2,1,1),(3,1,1),(4,1,1),(5,1,1),(6,1,1),(5,1,2),(5,2,2),(5,3,1),(6,3,2),(6,4,2),(6,5,3),(5,5,2),(5,6,2),(5,7,1),(6,7,1),(7,7,1),(8,7,1),(9,7,2),(9,8,0)
七.附录
#include
#include
using namespace std;
typedef struct {
int ord;
int x,y;
int di;
}elem;
elem **maze;
int i,j,m,n;
int c=0;
queue s;
void GoMaze(int x,int y){
if(x==(m-2)&&y==(n-2))
c++;
if(x+1
maze[x+1][y].ord=1;
maze[x][y].di=1;
s.push(maze[x][y]);
GoMaze(x+1,y);
maze[x+1][y].ord=0;
}
if(y+1
maze[x][y+1].ord=1;
maze[x][y].di=2;
s.push(maze[x][y]);
GoMaze(x,y+1);
maze[x][y+1].ord=0;
}
if(x-1>=0&&maze[x-1][y].ord==0&&c==0){
maze[x-1][y].ord=1;
maze[x][y].di=3;
s.push(maze[x][y]);
GoMaze(x-1,y);
maze[x-1][y].ord=0;
}
if(y-1>=0&&maze[x][y-1].ord==0&&c==0){
maze[x][y-1].ord=1;
ma
ze[x][y].di=4;
s.push(maze[x][y]);
GoMaze(x,y-1);
maze[x][y-1].ord=0;
}
if(!s.empty()){
elem t=s.front();
printf("(%d,%d,%d)\n",t.x,t.y,t.di);
s.pop();
}
}
int main(){
FILE *mazefile;
mazefile = fopen("maze.txt","r");
fscanf(mazefile,"%d %d\n",&m,&n);
maze = new elem*[m];
for (i=0;i
maze[i] = new elem [n];
for (i=0;i
for (int j=0;j
char ch;
fscanf(mazefile,"%c",&ch);
maze[i][j].ord=(ch-'0');
maze[i][j].x=i;
maze[i][j].y=j;
}
fscanf(mazefile,"\n");
}
GoMaze(1,1);
printf("(%d,%d,0)",m-2,n-2);
return 0;
}
数据结构实验报告
实习1 栈和队列及其应用
题目:迷宫问题
班级:1403011班 姓名:付尧 学号:[1**********] 完成日期:2015.11.25
一.需求分析
1.以二维数组maze[m][n]表示迷宫,再为周围加一圈障碍。数组以元素值为0表示通路,1表示障碍。
2.用户以文件的形式输入迷宫的数据:文件中第一行的数据为迷宫的行数m和列数n;从第二行到第m+1行(每行n个数)为迷宫值。
3.迷宫的入口位置默认为(1,1),出口位置默认为(m,n)。
4.程序执行的命令包括:
(1)创建迷宫;(2)求解迷宫;(3)输出迷宫的解;(4)结束。
5.测试数据
测试数据见原题,已存储在maze.txt文件中。输出内容为:(1,1,1),(2,1,1),(3,1,1),(4,1,1),(5,1,1),(6,1,1),(5,1,2),(5,2,2),(5,3,1),(6,3,2),(6,4,2),(6,5,3),(5,5,2),(5,6,2),(5,7,1),(6,7,1),(7,7,1),(8,7,1),(9,7,2),(9,8,0)
二.概要设计
为了实现程序上述功能,应以队列为存储结构。
1. 基本操作:
void GoMaze( )
操作结果:求解迷宫,并输出一条通路。
2. 本程序包含三个模块:
(1)构建迷宫及主程序模块;
(3)执行迷宫求解模块;
三.详细设计
1.元素类型,结点类型和指针类型:
typedef struct {
int ord;
int x,y;
int di;
int pre;
}elem;
elem **maze;
int i,j,m,n,a,b;
int c=0;
queue s;
6.每个模块的分析:
(1)构建迷宫及主程序模块:
int main(){
FILE *mazefile;
mazefile = fopen("maze.txt","r");
fscanf(mazefile,"%d %d\n",&a,&b); //读入行数和列数
m=a+2;
n=b+2; //在周围添加一圈障碍后的行数和列数
maze = new elem*[m];
for (i=0;i
maze[i] = new elem [n];
for (i=0;i
for (int j=0;j
char ch;
maze[i][j].x=i;
maze[i][j].y=j;
maze[i][j].pre=0;
maze[i][j].di=0;
if(i==0||j==0||i==m-1||j==n-1)
maze[i][j].ord=1;
else{
fscanf(mazefile,"%c",&ch);
maze[i][j].ord=(ch-'0');
}
}
fscanf(mazefile,"\n");
}
GoMaze(1,1); //执行迷宫求解函数
printf("(%d,%d,0)",m-2,n-2); //输出终点(迷宫求解函数只输出除终点外的路径)
return 0;
}
(2)执行迷宫求解模块:
void GoMaze(int x,int y){
if(x==(m-2)&&y==(n-2)) //创建计数器,保证递归终止条件
c++;
if(x+1
if(maze[x][y].pre==3) //弹出遇到死路的元素
s.pop();
else{
maze[x+1][y].ord=1;
maze[x][y].di
=1; //设立方向标志
maze[x+1][y].pre=1; //为此元素做标记,防止再次访问
s.push(maze[x][y]); //元素入队列
GoMaze(x+1,y); //进入递归
maze[x+1][y].ord=0; //将元素恢复
}
}
if(y+1
if(maze[x][y].pre==4)
s.pop();
else{
maze[x][y+1].ord=1;
maze[x][y].di=2;
maze[x][y+1].pre=2;
s.push(maze[x][y]);
GoMaze(x,y+1);
maze[x][y+1].ord=0;
}
}
if(x-1>=0&&maze[x-1][y].ord==0&&c==0){
if(maze[x][y].pre==1)
s.pop();
else{
maze[x-1][y].ord=1;
maze[x][y].di=3;
maze[x-1][y].ord=3;
s.push(maze[x][y]);
GoMaze(x-1,y);
maze[x-1][y].ord=0;
}
}
if(y-1>=0&&maze[x][y-1].ord==0&&c==0){
if(maze[x][y].pre==2)
s.pop();
else{
maze[x][y-1].ord=1;
maze[x][y].di=4;
maze[x][y-1].pre=4;
s.push(maze[x][y]);
GoMaze(x,y-1);
maze[x][y-1].ord=0;
}
}
while(!s.empty()){ //输出队列内已储存的通路
elem t=s.front();
printf("(%d,%d,%d),",t.x,t.y,t.di);
s.pop(); //弹出元素
}
}
四.调试分析
(1)设计过程中对递归结束的条件感到疑惑,经过考虑,设立了一个计数器c,解决问题。
(2)程序采用c++中queue函数,减少了c语言中构建队列的冗长代码,方便快捷。
(3)这道题第一眼看觉得仅仅是个递归的简单应用,但实际操作还是有很多需要考虑的地方,比如如何终止递归,防止其他函数再次执行函数。
五.用户使用说明
(1)本程序的运行环境为VS2010。
(2)进入演示程序后即直接输出结果。
六.测试结果
当正确添加文件,就可以得出结果(1,1,1),(2,1,1),(3,1,1),(4,1,1),(5,1,1),(6,1,1),(5,1,2),(5,2,2),(5,3,1),(6,3,2),(6,4,2),(6,5,3),(5,5,2),(5,6,2),(5,7,1),(6,7,1),(7,7,1),(8,7,1),(9,7,2),(9,8,0)
七.附录
#include
#include
using namespace std;
typedef struct {
int ord;
int x,y;
int di;
}elem;
elem **maze;
int i,j,m,n;
int c=0;
queue s;
void GoMaze(int x,int y){
if(x==(m-2)&&y==(n-2))
c++;
if(x+1
maze[x+1][y].ord=1;
maze[x][y].di=1;
s.push(maze[x][y]);
GoMaze(x+1,y);
maze[x+1][y].ord=0;
}
if(y+1
maze[x][y+1].ord=1;
maze[x][y].di=2;
s.push(maze[x][y]);
GoMaze(x,y+1);
maze[x][y+1].ord=0;
}
if(x-1>=0&&maze[x-1][y].ord==0&&c==0){
maze[x-1][y].ord=1;
maze[x][y].di=3;
s.push(maze[x][y]);
GoMaze(x-1,y);
maze[x-1][y].ord=0;
}
if(y-1>=0&&maze[x][y-1].ord==0&&c==0){
maze[x][y-1].ord=1;
ma
ze[x][y].di=4;
s.push(maze[x][y]);
GoMaze(x,y-1);
maze[x][y-1].ord=0;
}
if(!s.empty()){
elem t=s.front();
printf("(%d,%d,%d)\n",t.x,t.y,t.di);
s.pop();
}
}
int main(){
FILE *mazefile;
mazefile = fopen("maze.txt","r");
fscanf(mazefile,"%d %d\n",&m,&n);
maze = new elem*[m];
for (i=0;i
maze[i] = new elem [n];
for (i=0;i
for (int j=0;j
char ch;
fscanf(mazefile,"%c",&ch);
maze[i][j].ord=(ch-'0');
maze[i][j].x=i;
maze[i][j].y=j;
}
fscanf(mazefile,"\n");
}
GoMaze(1,1);
printf("(%d,%d,0)",m-2,n-2);
return 0;
}