数据结构课程设计 图的遍历.docx

上传人:b****5 文档编号:8200398 上传时间:2023-01-29 格式:DOCX 页数:21 大小:130.56KB
下载 相关 举报
数据结构课程设计 图的遍历.docx_第1页
第1页 / 共21页
数据结构课程设计 图的遍历.docx_第2页
第2页 / 共21页
数据结构课程设计 图的遍历.docx_第3页
第3页 / 共21页
数据结构课程设计 图的遍历.docx_第4页
第4页 / 共21页
数据结构课程设计 图的遍历.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

数据结构课程设计 图的遍历.docx

《数据结构课程设计 图的遍历.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计 图的遍历.docx(21页珍藏版)》请在冰豆网上搜索。

数据结构课程设计 图的遍历.docx

数据结构课程设计图的遍历

 

湖南人文科技学院计算机系

数据结构课程设计

 

课程名称

:

数据结构

课程代码

:

408024

题目

:

图的遍历

年级/专业/班

:

09级计算机科学与技术专业二班

学生姓名

:

学号

:

指导老师

:

朱素英

开题时间

:

2010-12-20

完成时间

:

2010-12-31

 

目录

摘要3

Abstract3

一、引言4

二、设计目的与任务4

三、设计方案与实施5

1、总体设计5

2、详细设计5

3、程序清单9

4、程序调试与体会14

5、运行结果(截图)14

四、结论20

五、致谢20

六、参考文献20

摘要

随着计算机科技发展的异常迅速,计算机技术也越来越为人们所利用,计算机已深入到人类社会的各个领域,在21世纪计算机技术势必将得到更大的发展。

数据结构是计算机程序设计的重要理论技术基础,是一门实践性非常强的课程,它不仅是计算机学科的核心课程,而且已经成为其他理工专业的热门选修课。

如果说高级语言程序设计课程对学生进行了结构化程序设计的初步训练,那么数据结构课程就是要培养其数据抽象能力。

掌握好数据结构很有利于对计算机程序的设计。

图是一种较线性表和树更为复杂的数据结构,本设计是对图进行深度和广度的遍历。

关键词:

图遍历递归邻接矩阵

Abstract

Alongwiththedevelopmentofcomputertechnology,computertechnologyandunusuallyquickforpeopleplacemoreandmoreuse,computerisdeeplyintoeveryfieldofhumansociety,computertechnologyinthe21stcenturywhichwillbemorebigdevelopment.Datastructureistheimportanttheorycomputerprogrammingtechnologybase,isakindofverystrongpracticalitycourseofcomputerscience,itisnotonlythecorecurriculum,andhasbecomethehottestothertechprofessionalelectivecourse.Ifahighlevellanguageprogramdesigncourseforstudentshadastructuredprogrammingthepreliminarytraining,thenthedatastructurecourseistodevelopitsdataabstractionsability.Goodmasteryofdatastructureisverybeneficialtothedesignofacomputerprogram.

Figureisakindofmorelinearlistandtreesmorecomplexdatastructure,thedesignisthegraphdepthandbreadthofthetraverse.

Keywords:

FigureTraversalRecursionTheadjacencymatrix

《数据结构》课程设计

图的遍历设计

一、引言

数据结构是计算机存储、组织数据的方式,是指相互之间存在一种或多种特定关系的数据元素的集合。

通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。

数据结构往往同高效的检索算法和索引技术有关。

图是种较线性表和树更为复杂的数据结构。

在图形结构中,顶点之间的关系可以是任意的,任意两个元素之间都可能有相关的关系,这就优于了线性表。

图的遍历包括图的广度优先遍历与深度优先遍历。

对于广度优先遍历应利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)来实现,而深度优先搜索则是一种递归的过程。

二、设计目的与任务

1、设计目的是:

该设计要求学生本学期对数据结构的学习为背景,设计出一个简单的能够实现图的遍历的系统。

通过该题目的设计过程,主要达到如下目的:

(1)加深理解图、图的遍历、图的广度优先遍历、图的深度优先遍历、图的创建等一系列算法的创建,进一步理解和熟练掌握课本中所学的各种数据结构。

(2)熟悉图的结构和其基本操作,掌握数组的建立和使用方法,学会利用递归和非递归的方法对其进行遍历。

(3)学会如何把学到的知识用于解决实际问题,培养学生的动手能力。

(4)能在设计的过程中学会文档的写作和设计,以及提高团队合作能力。

2、设计任务是:

从键盘上输入一个图的基本信息(图用邻矩阵表示),输出这个图的遍历序列:

A)首先输入图的结点数->num。

B)依次输入图的各条边(数据之间用空格隔开)。

C)输出的形式:

按用户选择的遍历方法给出遍历顺序。

D)程序所能达到的功能:

能够按要求输出所要的结果。

三、设计方案与实施

1、总体设计

(1)使用键盘的操作实行各种信息的输入(包括图的结点、结点之间的连线),并将相应结果输出等功能;

(2)建立图,规定图的结点的个数少于二十个,实现图的遍历;

(3)算法对于一些精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明要求的结果,对算法实现过程中的异常情况能给出出错信息;

(4)图的遍历的方法有广度优先遍历和深度优先遍历,按照输入的要求实现图的两种遍历,并且输出结果。

程序流图如下:

 

2、详细设计

部分重点的函数详细设计如下:

1.图的创建:

该课题主要是以邻接矩阵的方式存储图,并以图形的方式输出图,所以在图的创建的过程中主要是输入图中各结点的关系,比方说1号结点和2号结点之间有联系,那么就得输入1,2,但是总得设置一个结束的条件,在这里我就以0,0结束,这样比较好控制。

而且初始化时得把所有邻接矩阵都初始化为0,那么当两个结点有关系时就可以设置为1.

voidCreateGraph(Graph*g,intn)/*创建图*/

{

inti,j,r1,r2;

g->vexnum=n;/*顶点数*/

for(i=1;i<=n;i++)/*顶点用i表示*/

{

g->V[i]=i;

}

for(i=1;i<=n;i++)/*初始化R*/

for(j=1;j<=n;j++)

{

g->R[i][j]=0;

}

printf("顶点1、顶点2:

\n");/*输入R*/

scanf("%d,%d",&r1,&r2);

while(r1!

=0&&r2!

=0)/*输入的边都赋值为1*/

{

g->R[r1][r2]=1;

g->R[r2][r1]=1;

scanf("%d,%d",&r1,&r2);

}

}

2.深度递归遍历:

当用户需要深度优先遍历时,由于公共变量Visited里的值可能会受到其他的变化,所以一开始就把所有结点都定义为未访问,然后当其访问到哪个结点时再把相应的结点的Visited设置为1,即已经访问。

再用VisitVex函数显示该结点已访问。

再查找该结点的下一个结点,实行递归。

直到所有的结点都已经访问完。

这是一个递归的过程。

所以在实现深度优先遍历的过程中必须递归调用深度优先搜索函数。

而且在深度优先搜索函数中必须设一标志数组以标记结点是否被访问。

voidDFS(Graph*g,intvex)/*深度递归遍历*/

{

intw;

Visited[vex]=1;/*对已经访问好的顶点标记为1*/

VisitVex(g,vex);/*访问顶点*/

for(w=FirstAdjVex(g,vex);w>0;w=NextAdjVex(g,vex,w))

/*获取下一个未被访问的邻接节点*/

if(!

Visited[w])/*如果顶点没有被访问过*/

{DFS(g,w);}/*深度递归遍历*/

}

voidDFSTraverse(Graph*g)

{

inti;

for(i=1;i<=g->vexnum;i++)/*初始化标志数组*/

Visited[i]=0;

for(i=1;i<=g->vexnum;i++)

if(!

Visited[i])/*如果顶点没有被访问过*/

{DFS(g,i);}/*调用深度递归遍历*/

}

3.广度遍历:

当用户需要广度优先遍历时,首先得初始化一个队列,并初始化其为一个空队列。

而且由于公共变量visited里的值可能会受到其他的变化,所以一开始就把所有结点都定义为未访问,然后当其访问到哪个结点时再把相应的结点的visited设置为1,即已经访问。

再用visitvex函数显示该结点已访问。

然后再把该结点入队。

只要队不为空。

就把队里的结点出队。

并查找下一个结点,直到所有的结点都已经访问完。

voidBFSTraverse(Graph*g,intv)/*广度遍历*/

{

inti;

Queue*q=(Queue*)malloc(sizeof(Queue));

for(i=1;i<=g->vexnum;i++)/*初始化标志数组*/

{Visited[i]=0;}

InitQueue(q);/*初始化队列*/

EnQueue(q,v);/*让要求遍历的第一个顶点入队*/

VisitVex(g,v);/*输出第一个顶点的遍历结果*/

Visited[v]=1;/*标记第一个顶点*/

while(Quempty(q))/*队列非空*/

{

intu,w;

u=DeQueue(q);/*出队*/

for(w=FirstAdjVex(g,u);w>0;w=Next(g,u,w))

if(!

Visited[w])/*如果顶点没有被访问过*/

{

Visited[w]=1;/*对已经访问好的顶点标记为1*/

VisitVex(g,w);/*访问顶点*/

EnQueue(q,w);/*入队*/

}

}

}

4.主函数:

主程序设计为:

intmain()

{

创建图

以邻接矩阵输出矩阵

输入要遍历的起始点

选择需要的操作

调用深度遍历函数

创建队列

调用广度优先遍历

输出矩阵

}

3、程序清单

#include

#include

#defineM20

typedefstruct/*定义图*/

{

intV[M];

intR[M][M];

intvexnum;

}Graph;

voidCreateGraph(Graph*g,intn)/*创建图*/

{

inti,j,r1,r2;

g->vexnum=n;

for(i=1;i<=n;i++)/*顶点用i表示*/

{

g->V[i]=i;

}

for(i=1;i<=n;i++)/*初始化R*/

for(j=1;j<=n;j++)

{

g->R[i][j]=0;

}

printf("顶点1、顶点2:

\n");/*输入R*/

scanf("%d,%d",&r1,&r2);

while(r1!

=0&&r2!

=0)

{

g->R[r1][r2]=1;

g->R[r2][r1]=1;

scanf("%d,%d",&r1,&r2);

}

}

voidPrintGraph(Graph*g)/*打印图的邻接矩阵*/

{

inti,j;

for(i=1;i<=g->vexnum;i++)

{for(j=1;j<=g->vexnum;j++)

{

printf("%2d",g->R[i][j]);

}

printf("\n");

}

printf("\n");

}

intVisited[M];/*全局变量:

访问标志数组*/

voidVisitVex(Graph*g,intvex)/*访问顶点*/

{

printf("%d",g->V[vex]);

}

intFirstAdjVex(Graph*g,intvex)/*获取第一个未被访问的邻接节点*/

{

intw,i;

for(i=1;i<=g->vexnum;i++)

{

if(g->R[vex][i]==1&&Visited[i]==0)

{

w=i;

break;

}

else

{

w=0;

}

}

returnw;

}

intNextAdjVex(Graph*g,intvex,intw)/*获取下一个未被访问的邻接节点(深度遍历)*/

{

intt;

t=FirstAdjVex(g,w);

returnt;

}

intNext(Graph*g,intvex,intw)/*获取下一个未被访问的邻接节点(广度遍历)*/

{

intt=0;

for(inti=w+1;i<=g->vexnum;i++)

if(g->R[vex][i]==1&&Visited[i]==0)

{

t=i;

break;

}

returnt;

}

voidDFS(Graph*g,intvex)/*深度递归遍历*/

{

intw;

Visited[vex]=1;

VisitVex(g,vex);

for(w=FirstAdjVex(g,vex);w>0;w=NextAdjVex(g,vex,w))

if(!

Visited[w])

{

DFS(g,w);

}

}

voidDFSTraverse(Graph*g,intv)

{

inti;

for(i=1;i<=g->vexnum;i++)

Visited[i]=0;

for(i=v;i<=g->vexnum;i++)

if(!

Visited[i])

{DFS(g,i);}

}

typedefstruct/*定义队列*/

{

intV[M];

intfront;

intrear;

}Queue;

voidInitQueue(Queue*q)/*初始化队列*/

{

q->front=0;

q->rear=0;

}

intQuempty(Queue*q)/*判断队列是否为空*/

{

if(q->front==q->rear)

{

return0;

}

else

{

return1;

}

}

intEnQueue(Queue*q,inte)/*入队操作*/

{

if((q->rear+1)%M==q->front)

{

printf("队已满!

\n");

return0;

}

else

{

q->V[q->rear]=e;

q->rear=(q->rear+1)%M;

return1;

}

}

intDeQueue(Queue*q)/*出队操作*/

{

intt;

if(q->front==q->rear)

{

printf("队为空!

\n");

return0;

}

else

{

t=q->V[q->front];

q->front=(q->front+1)%M;

returnt;

}

}

voidBFSTraverse(Graph*g,intv)/*广度遍历*/

{

inti;

Queue*q=(Queue*)malloc(sizeof(Queue));

for(i=1;i<=g->vexnum;i++)

{

Visited[i]=0;

}

InitQueue(q);

EnQueue(q,v);

VisitVex(g,v);

Visited[v]=1;

while(Quempty(q))

{

intu,w;

u=DeQueue(q);

for(w=FirstAdjVex(g,u);w>0;w=Next(g,u,w))

if(!

Visited[w])

{

Visited[w]=1;

VisitVex(g,w);

EnQueue(q,w);

}

}

}

intmain()/*主程序*/

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

printf("welcome\n\n");

printf("图的遍历\n\n");

printf("成员:

\n\n\n\n\n\n");

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

system("pause");

system("cls");

intnum,v;

Graph*g=(Graph*)malloc(sizeof(Graph));

charmenu;

printf("请输入节点的个数num:

\n");

scanf("%d",&num);

CreateGraph(g,num);

printf("以邻接矩阵输出:

\n");

PrintGraph(g);

system("pause");

input:

printf("选择遍历的起始点:

\n");

scanf("%d",&v);

printf("请选择需要的操作:

\n广度优先遍历输入b,深度优先遍历输入d,退出输入q\n");

while((menu=getchar())=='\n');

if(menu=='b')

{

printf("广度优先遍历:

\n");

BFSTraverse(g,v);

printf("\n");

system("pause");

system("cls");

gotoinput;

}

elseif(menu=='d')

{

printf("深度优先遍历:

\n");

DFSTraverse(g,v);

printf("\n");

system("pause");

system("cls");

gotoinput;

}

elseif(menu=='q')

{

printf("\n");

exit(0);

}

else

{

printf("\n输入有误!

\n");

system("pause");

system("cls");

gotoinput;

}

system("pause");

return1;

}

3、程序调试与体会

先进行对创建矩阵的函数进行调试,在确保无误的情况下再进行后面模块的调试,在调试中间经常会出现一些小问题,这时候需要采用“隔离”的方法进行逐步的排查。

最后对整个程序进行总体的调试,不断完善一些细节方面,并对输入的参数进行多方面的改变,以确保程序的正确性。

在整个程序运行无误的基础上,在尽力对一些函数进行优化,加强程序的可读性,方便性。

在调试中,团队的协调让调试过程充满了活力和激情,让我们感受到团队合作的重要性。

在指导老师朱素英老师的指导和建议下,我们对程序又进行了适当的修改,老师的辛勤努力,让我们明白有位优秀指导老师的必要性。

4、运行结果

截图1,点击编译,运行,初始状态的欢迎界面如下图:

截图2,按任意键继续,要求输入节点数num,节点数要求为小于二十,本次课程设计调试运行实验中,我们输入了8,并输入了相应的边,输入边的信息时,以0,0结束输入:

截图3,按回车键,以邻接矩阵的形式输出图:

截图4,按任意键继续,要求选择遍历的起始点,这里我们以5为起始点:

截图5,要求选择需要的操作,本次课程设计运行实验中,我们先选择广度优先遍历,输入b:

截图6,输出广度优先遍历的遍历顺序,按任意键继续,要求选择需要执行遍历的起始点,我们输入6,并选择深度优先遍历:

截图7,按任意键继续,为验证输入错误情况,这次刻意输入错误操作字母代码,我们输入了s:

提示输入有错误,并要求输入任意键继续。

调试完全正确,成功调试后,选择退出,输入q,结束调试。

四、结论

图的遍历的整体思想并不复杂,利用邻接矩阵作为存储结构(邻接矩阵主要又是对数组的利用),对某个顶点访问之后再判断是否有邻接点,有则对其邻接点进行访问,否则寻找下个未被访问的顶点,这个过程就利用了递归的方法。

在进行具体的实现的时候则将独立的需要多次调用的内容独自开辟个函数,以便进行多次调用,也能够加强程序的可读性。

通过两周的课程设计,充分认识到《数据结构》这门课的重要性。

它给我们一个思想和大纲,让我们在编程时容易找到思路,不至于无章可循。

同时它也有广泛的实际应用。

总之,在这次课程设计中,自己的C语言与数据结构知识得到提高,编程能力也得到了提高。

积累了经验,锻炼了自己分析问题和解决问题的能力,掌握了必要的文档写作知识,懂得了制作规范和要求,并学会了如何将所学的各课知识融会组织,来配合学习,以及感受到团队合作的力量。

两周中我收益很大,学到很多。

五、致谢

首先,非常非常感谢我们的辅导老师朱素英老师,在她的数次精心辅导和帮助下,我们的课程设计才得以顺利的完成,在她的带领下,我们学到了更多的东西。

其次,要对我们的这个团体表示衷心的感谢,因为只有团体的共同努力才能让我们顺利而又快速的完成本次的课程设计,在本次的课程设计中,我们真正感受到了团队合作的重要性。

最后,也要在此谢谢在这个过程给予了我们许多帮助许多照顾的同学们和机房的各位老师,在他们的帮助下,我们的设计才能做的更好更顺利。

六、参考文献

[1]C语言程序设计教程.杨路明,北京邮电大学出版社,2005,1

[2]C语言程序设计.谭浩强

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1