搜档网
当前位置:搜档网 › 数据结构课程设计报告范例

数据结构课程设计报告范例

数据结构课程设计报告范例
数据结构课程设计报告范例

Guangxi University of Science and Technology 课程设计报告

课程名称:算法与编程综合实习

课题名称:

姓名:

学号:

院系:计算机学院

专业班级:通信121

指导教师:

完成日期:2012年12月15日

目录

第1部分课程设计报告 (3)

第1章课程设计目的 (3)

第2章课程设计内容和要求 (4)

2.1 问题描述 (4)

2.2 设计要求 (4)

第3章课程设计总体方案及分析 (4)

3.1 问题分析 (4)

3.2 概要设计 (7)

3.3 详细设计 (7)

3.4 调试分析 (10)

3.5 测试结果 (10)

3.6 参考文献 (12)

第2部分课程设计总结 (13)

附录(源代码) (14)

第1部分课程设计报告

第1章课程设计目的

仅仅认识到队列是一种特殊的线性表是远远不够的,本次实习的目的在于使学生深入了解队列的特征,以便在实际问题背景下灵活运用它,同时还将巩固这种数据结构的构造方………………………………………………………………………………………………………………………………………………………………………………………..(省略)

第2章课程设计内容和要求

2.1问题描述:

迷宫问题是取自心理学的一个古典实验。在该实验中,把一只老鼠从一个无顶大盒子的门放入,在盒子中设置了许多墙,对行进方向形成了多处阻挡。盒子仅有一个出口,在出口处放置一块奶酪,吸引老鼠在迷宫中寻找道路以到达出口。对同一只老鼠重复进行上述实验,一直到老鼠从入口走到出口,而不走错一步。老鼠经过多次试验最终学会走通迷宫的路线。设计一个计算机程序对任意设定的矩形迷宫如下图A所示,求出一条从入口到出口的通路,或得出没有通路的结论。

图A

2.2设计要求:

要求设计程序输出如下:

(1) 建立一个大小为m×n的任意迷宫(迷宫数据可由用户输入或由程序自动生成),并在屏

幕上显示出来;

(2)找出一条通路的二元组(i,j)数据序列,(i,j)表示通路上某一点的坐标。

(3)用一种标志(如数字8)在迷宫中标出该条通路;

(4)在屏幕上输出迷宫和通路;

(5)上述功能可用菜单选择。

第3章课程设计总体方案及分析

3.1 问题分析:

1.迷宫的建立:

迷宫中存在通路和障碍,为了方便迷宫的创建,可用0表示通路,用1表示障碍,这样迷宫就可以用0、1矩阵来描述,

2.迷宫的存储:

迷宫是一个矩形区域,可以使用二维数组表示迷宫,这样迷宫的每一个位置都可以用其行列号来唯一指定,但是二维数组不能动态定义其大小,我们可以考虑先定义一个较大的二维数组maze[M+2][N+2],然后用它的前m行n列来存放元素,即可得到一个m×n的二维数组,这样(0,0)表示迷宫入口位置,(m-1,n-1)表示迷宫出口位置。

注:其中M,N分别表示迷宫最大行、列数,本程序M、N的缺省值为39、39,当然,用户也可根据需要,调整其大小。

3.迷宫路径的搜索:

首先从迷宫的入口开始,如果该位置就是迷宫出口,则已经找到了一条路径,搜索工作结束。否则搜索其上、下、左、右位置是否是障碍,若不是障碍,就移动到该位置,然后再从该位置开始搜索通往出口的路径;若是障碍就选择另一个相邻的位置,并从它开始搜索路径。为防止搜索重复出现,则将已搜索过的位置标记为2,同时保留搜索痕迹,在考虑进入下一个位置搜索之前,将当前位置保存在一个队列中,如果所有相邻的非障碍位置均被搜索过,且未找到通往出口的路径,则表明不存在从入口到出口的路径。这实现的是广度优先遍历的算法,如果找到路径,则为最短路径。

以矩阵 0 0 1 0 1 为例,来示范一下

1 0 0 1 0

1 0 0 0 1

0 0 1 0 0

首先,将位置(0,0)(序号0)放入队列中,其前节点为空,从它开始搜索,其标记变为2,由于其只有一个非障碍位置,所以接下来移动到(0,1)(序号1),其前节点序号为

0,标记变为2,然后从(0,1)移动到(1,1)(序号2),放入队列中,其前节点序号为1,(1,1)存在(1,2)(序号3)、(2,1)(序号4)两个可移动位置,其前节点序号均为2.对于每一个非障碍位置,它的相邻非障碍节点均入队列,且它们的前节点序号均为该位置的序号,所以如果存在路径,则从出口处节点的位置,逆序就可以找到其从出口到入口的通路。

如下表所示:

0 1 2 3 4 5 6 7 8 9 10

由此可以看出,得到最短路径:(3,4)(3,3)(2,3)(2,2)(1,2)(1,1)(0,1)(0,0)

搜索算法流程图如下所示:

3.2 概要设计

1.①构建一个二维数组maze[M+2][N+2]用于存储迷宫矩阵

②自动或手动生成迷宫,即为二维数组maze[M+2][N+2]赋值

③构建一个队列用于存储迷宫路径

④建立迷宫节点struct point,用于存储迷宫中每个节点的访问情况

⑤实现搜索算法

⑥屏幕上显示操作菜单

2.本程序包含10个函数:

(1)主函数 main()

(2)手动生成迷宫函数 shoudong_maze()

(3)自动生成迷宫函数 zidong_maze()

(4)将迷宫打印成图形 print_maze()

(5)打印迷宫路径 (若存在路径) result_maze()

(6)入队 enqueue()

(7)出队 dequeue()

(8)判断队列是否为空 is_empty()

(9)访问节点 visit()

(10)搜索迷宫路径 mgpath()

3.3 详细设计

实现概要设计中定义的所有数据类型及操作的伪代码算法

1.节点类型和指针类型

迷宫矩阵类型:int maze[M+2][N+2];为方便操作使其为全局变量

迷宫中节点类型及队列类型:struct point{int row,col,predecessor} que[512]

2.迷宫的操作

(1)手动生成迷宫

void shoudong_maze(int m,int n)

{定义i,j为循环变量

for(i<=m)

for(j<=n)

输入maze[i][j]的值

}

(2)自动生成迷宫

void zidong_maze(int m,int n)

{定义i,j为循环变量

for(i<=m)

for(j<=n)

maze[i][j]=rand()%2 //由于rand()产生的随机数是从0到

RAND_MAX,RAND_MAX是定义在stdlib.h中的,其值

至少为32767),要产生从X到Y的数,只需要这样

写:k=rand()%(Y-X+1)+X;

}

(3)打印迷宫图形

void print_maze(int m,int n)

{用i,j循环变量,将maze[i][j]输出□、■}

(4)打印迷宫路径

void result_maze(int m,int n)

{用i,j循环变量,将maze[i][j]输出□、■、☆}

(5)搜索迷宫路径

①迷宫中队列入队操作

void enqueue(struct point p)

{将p放入队尾,tail++}

②迷宫中队列出队操作

struct point dequeue(struct point p)

{head++,返回que[head-1]}

③判断队列是否为空

int is_empty()

{返回head==tail的值,当队列为空时,返回0}

④访问迷宫矩阵中节点

void visit(int row,int col,int maze[41][41])

{建立新的队列节点visit_point,将其值分别赋为row,col,head-1,maze[row][col]=2,表示该节点以被访问过;调用

enqueue(visit_point),将该节点入队}

⑤路径求解

void mgpath(int maze[41][41],int m,int n)

{先定义入口节点为struct point p={0,0,-1},从maze[0][0]开始访问。如果

入口处即为障碍,则此迷宫无解,返回0 ,程序结束。否则访问入口节点,

将入口节点标记为访问过maze[p.row][p.col]=2,调用函数enqueue(p)将该

节点入队。

判断队列是否为空,当队列不为空时,则运行以下操作:

{ 调用dequeue()函数,将队头元素返回给p,

如果p.row==m-1且p.col==n-1,即到达出口节点,即找到了路径,结束

如果p.col+1

其右方有通路,则visit(p.row,p.col+1,maze),将右边节点入队标

记已访问

如果p.row+1

其下方有通路,则visit(p.row+1,p.col,maze),将下方节点入队标

记已访问

如果p.col-1>0且maze[p.row][p.col-1]==0,说明未到迷宫左边界,且

其左方有通路,则visit(p.row,p.col-1,maze),将左方节点入队标

记已访问

如果p.row-1>0且maze[p.row-1][p.col]==0,说明未到迷宫上边界,且

其上方有通路,则visit(p.row,p.col+1,maze),将上方节点入队标

记已访问

}

访问到出口(找到路径)即p.row==m-1且p.col==n-1,则逆序将路径标记为3

即maze[p.row][p.col]==3;

while(p.predecessor!=-1)

{p=queue[p.predecessor]; maze[p.row][p.col]==3;}

最后将路径图形打印出来。

3.菜单选择

while(cycle!=(-1))

☆手动生成迷宫请按:1

☆自动生成迷宫请按:2

☆退出请按:3

scanf("%d",&i);

switch(i)

{case 1:请输入行列数(如果超出预设范围则提示重新输入)

shoudong_maze(m,n);

print_maze(m,n);

mgpath(maze,m,n);

if(X!=0) result_maze(m,n);

case 2:请输入行列数(如果超出预设范围则提示重新输入)

zidong_maze(m,n);

print_maze(m,n);

mgpath(maze,m,n);

if(X!=0) result_maze(m,n);

case 3:cycle=(-1);break;

}

注:具体源代码见附录

3.4 调试分析

在调试过程中,首先使用的是栈进行存储,但是产生的路径是多条或不是最短路径,所以通过算法比较,改用此算法

3.5 测试结果

1.手动输入迷宫

2.自动生成迷宫

3.6 参考文献

【1】严蔚敏吴伟民《数据结构(C语言版)》清华大学出版社, 2009年9月【2】谭浩强《C程序设计(第三版)》清华大学出版社 2009年1月

第2部分课程设计总结

通过这段时间的课程设计,本人对计算机的应用,数据结构的作用以及C语言的使用都有了更深的了解。尤其是C语言的进步让我深刻的感受到任何所学的知识都需要实践,没有实践就无法真正理解这些知识以及掌握它们,使其成为自己的财富。在理论学习和上机实践的各个环节中,通过自主学习和请教老师,我收获了不少。当然也遇到不少的问题,也正是因为这些问题引发的思考给我带了收获。从当初不喜欢上机写程序到现在能主动写程序,从当初拿着程序不只如何下手到现在知道如何分析问题,如何用专业知识解决实际问题的转变,我发现无论是专业知识还是动手能力,自己都有很大程度的提高。在这段时间里,我对for、while等的循环函数用法更加熟悉,逐渐形成了较好的编程习惯。在老师的指导帮助下,同学们课余时间的讨论中,这些问题都一一得到了解决。在程序的调试能力上,无形中得到了许多的提高。例如:头文件的使用,变量和数组的范围问题,定义变量时出现的问题等等。

在实际的上机操作过程中,不仅是让我们了解数据结构的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次实习可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。

在这次短短的课程实践里,我们得到了**老师的关心和帮助。她给了我们很多的信息,与我们一起探讨问题,询问我们遇到了哪些问题并耐心给予指导。当我们遇到技术上难以解决的问题时,她就会指导我们解决问题,她把自己多年来积累的经验教授给我们,使我们顺利地完成了课程实践任务。时间过得真快,大学生活不知不觉就走过了一年,一年的大学学习和课程实践阶段的提高,使我们本身知识得到提高的同时,也增强了我们对未来工作的信心,我们相信自己未来三年的学习更使我们有能力胜任将来的工作。

附录

#include"stdlib.h"

#include"stdio.h"

#define N 39

#define M 39

int X;

int maze[N+2][M+2];

struct point{

int row,col,predecessor;

}queue[512];

int head=0,tail=0;

void shoudong_maze(int m,int n){

int i,j;

printf("\n\n");

printf("请按行输入迷宫,0表示通路,1表示障碍:\n\n");

for(i=0;i

for(j=0;j

scanf("%d",&maze[i][j]);

}

void zidong_maze(int m,int n){

int i,j;

printf("\n迷宫生成中……\n\n");

system("pause");

for(i=0;i

for(j=0;j

maze[i][j]=rand()%2;

//由于rand()产生的随机数是从0到RAND_MAX

//RAND_MAX是定义在stdlib.h中的,其值至少为32767)

//要产生从X到Y的数,只需要这样写:k=rand()%(Y-X+1)+X; }

void print_maze(int m,int n){

int i,j;

printf("\n迷宫生成结果如下:\n\n");

printf("迷宫入口\n");

printf("↓");

for(i=0;i

{printf("\n");

for(j=0;j

{if(maze[i][j]==0) printf("□");

if(maze[i][j]==1) printf("■");}

}

printf("→迷宫出口\n");

}

void result_maze(int m,int n){

int i,j;

printf("迷宫通路(用☆表示)如下所示:\n\t");

for(i=0;i

{printf("\n");

for(j=0;j

{if(maze[i][j]==0||maze[i][j]==2) printf("□");

if(maze[i][j]==1) printf("■");

if(maze[i][j]==3) printf("☆");

}

}

}

void enqueue(struct point p){

queue[tail]=p;

tail++;

}

struct point dequeue(){

head++;

return queue[head-1];

}

int is_empty(){

return head==tail;

}

void visit(int row,int col,int maze[41][41]){

struct point visit_point={row,col,head-1};

maze[row][col]=2;

enqueue(visit_point);

}

int mgpath(int maze[41][41],int m,int n){

X=1;

struct point p={0,0,-1};

if(maze[p.row][p.col]==1)

{printf("\n===============================================\n");

printf("此迷宫无解\n\n");X=0;return 0;}

maze[p.row][p.col]=2;

enqueue(p);

while(!is_empty())

{p=dequeue();

if((p.row==m-1)&&(p.col==n-1)) break;

if((p.col+1

if((p.row+1

if((p.col-1>=0)&&(maze[p.row][p.col-1]==0)) visit(p.row,p.col-1,maze);

if((p.row-1>=0)&&(maze[p.row-1][p.col]==0)) visit(p.row-1,p.col,maze);

}

if(p.row==m-1&&p.col==n-1)

{printf("\n==================================================================\n");

printf("迷宫路径为:\n");

printf("(%d,%d)\n",p.row,p.col);

maze[p.row][p.col]=3;

while(p.predecessor!=-1)

{p=queue[p.predecessor];

printf("(%d,%d)\n",p.row,p.col);

maze[p.row][p.col]=3;

}

}

else {printf("\n=============================================================\n");

printf("此迷宫无解!\n\n");X=0;}

return 0;

}

void main()

{int i,m,n,cycle=0;

while(cycle!=(-1))

{

printf("********************************************************************************\n"); printf(" 欢迎进入迷宫求解系统\n");

printf(" 设计者:吴明华\n"); printf("********************************************************************************\n"); printf(" ☆手动生成迷宫请按:1\n");

printf(" ☆自动生成迷宫请按:2\n");

printf(" ☆退出请按:3\n\n");

printf("********************************************************************************\n"); printf("\n");

printf("请选择你的操作:\n");

scanf("%d",&i);

switch(i)

{case 1:printf("\n请输入行数:");scanf("%d",&m);

printf("\n");

printf("请输入列数:");scanf("%d",&n);

while((m<=0||m>39)||(n<=0||n>39))

{printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入:\n\n");

printf("请输入行数:");scanf("%d",&m);

printf("\n");

printf("请输入列数:");scanf("%d",&n);

}

shoudong_maze(m,n);

print_maze(m,n);

mgpath(maze,m,n);

if(X!=0) result_maze(m,n);

printf("\n\nPress Enter Contiue!\n");getchar();while(getchar()!='\n');break;

case 2:printf("\n请输入行数:");scanf("%d",&m);

printf("\n");

printf("请输入列数:");scanf("%d",&n);

while((m<=0||m>39)||(n<=0||n>39))

{printf("\n抱歉,你输入的行列数超出预设范围(0-39,0-39),请重新输入:\n\n");

printf("请输入行数:");scanf("%d",&m);

printf("\n");

printf("请输入列数:");scanf("%d",&n);

}

zidong_maze(m,n);

print_maze(m,n);

mgpath(maze,m,n);

if(X!=0) result_maze(m,n);

printf("\n\nPress Enter Contiue!\n");getchar();while(getchar()!='\n');break; case 3:cycle=(-1);break;

default:printf("\n");printf("你的输入有误!\n");

printf("\nPress Enter Contiue!\n");getchar();while(getchar()!='\n');break;

}

}

}

相关主题