数据结构课程设计.docx

上传人:b****7 文档编号:23936489 上传时间:2023-05-22 格式:DOCX 页数:23 大小:175.01KB
下载 相关 举报
数据结构课程设计.docx_第1页
第1页 / 共23页
数据结构课程设计.docx_第2页
第2页 / 共23页
数据结构课程设计.docx_第3页
第3页 / 共23页
数据结构课程设计.docx_第4页
第4页 / 共23页
数据结构课程设计.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

数据结构课程设计.docx

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

数据结构课程设计.docx

数据结构课程设计

 

课程设计说明书

 

课程名称:

数据结构与算法

设计题目:

图的遍历和生成树的求解

院系:

计算机科学与信息工程学院

学生姓名:

学号:

专业班级:

计算机科学与技术(嵌入式方向)11-1

指导教师:

 

2013年6月

课程设计任务书

设计题目

图的遍历和生成树的求解

学生姓名

韩银奇

所在院系

计算机科学与信息工程系

专业、年级、班

计算机科学与技术(嵌入式方向)11-1

设计要求:

1)先任意创建一个无向图;

2)能够输出显示生成的无向图的顶点和边的信息

3)输出该图的深度和广度遍历序列

4)通过普利姆算法和克鲁斯卡尔算法求最小生成树,并输出最小生成树的求解构造过程

学生应完成的工作:

(1)根据课程设计要求,分析思路并构建模型,划分子模块、完善其功能;

(2)根据各模块的功能设计并编写程序段、连接各程序段使之形成一个有机的整体;

(3)调试、运行程序进而得到正确的结果;

(4)根据实验设计运行过程,写出实验论文并总结实验教训。

参考文献阅读:

(1)C语言程序设计(潭浩强第二版,清华大学出版社);

(2)数据结构(严蔚敏、吴伟民C语言版,清华大学出版社);

(3)数据结构实验教程(高晓兵等,清华大学出版社);

(4)钱能.C++程序设计教程第二版.北京:

清华大学出版社.2005;

(5)李兰,刘天印.C++程序设计实验指导.北京:

北京大学出版社.2006。

工作计划:

(1)第一周的第一天:

小组布置设计题目;说明进度安排。

(2)第一周的第二天:

小组审题,查阅资料,进行设计前的必要资料准备。

(3)第一周的第三天、第四天、第五天:

程序编写、上机调试

(4)第二周的第一天至第三天:

上机调试程序、结果分析。

(5)第二周的第四天:

撰写设计报告。

(6)第二周的第五天:

设计答辩。

任务下达日期:

2013年6月14日

任务完成日期:

2013年6月28日

指导教师(签名):

学生(签名):

图的遍历和最小生成树的求解

摘要:

图是一种复杂的非线性数据结构,一个图G(Grah)由两个集合V和E构成,图存在两种遍历方式,深度优先遍历和广度优先遍历,广度优先遍历基本思路是假设从图中某顶点U出发,在访问了顶点U之后依次访问U的各个未访问的领接点,然后分别从这些领接点出发依次访问他们的领接点,并使先访问的顶点的领接点先于后访问的顶点被访问。

直至所有领接点被访问到。

深度优先的基本思路是从某个顶点出发,访问此顶点,然后依次从V的未被访问的领接点出发深度优先检索土。

直至图中所有顶点都被访问到。

在计算机中,图的信息有多种存储方法,由于图的结构复杂,使用广泛,一般应根据实际的应用,选择适合的表示方法。

常用的图的存储结构有邻接矩阵、邻接链表等。

关键词:

图的遍历;邻接矩阵;邻接链表

 

目录

1.设计背景1

1.1图形结构的广泛应用1

1.2图的需求1

1.3最小生成树的需求与应用1

2.设计方案2

2.1总体设计流程2

2.2软件结构设计:

2

2.3函数程序流程图3

3.方案实施4

3.1图的遍历邻接矩阵的实现4

3.2图的遍历邻接表的存储4

4.结果与结论4

4.1源程序代码概要4

4.2主函数和其他函数的伪码算法5

4.3程序运行结果11

4.4课程设计总结13

5.收获与致谢13

6.参考文献14

7.附件14

1.设计背景

1.1图形结构的广泛应用

图有若干各节点和若干条边构成的结构,是一类重要的非线性数据结构。

图形结构在客观世界中广泛存在,特别是近年来的迅速发展,已渗入到诸如语言学、逻辑学、物理、化学、电讯工程及数学的其他分支中,图在计算机领域中也得到广泛应用,如在编译程序中,可以用图来表示源程序的语法结构。

又如在数据库系统中,图形结构也是信息的重要组织之一。

1.2图的需求

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

在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。

由此,图的应用极为广泛,特别是近年来的迅速发展,已渗入到诸如语言学、逻辑学、物理、化学、电讯工程、计算机科学以及数学的其他分支中

任意创建一个无环图,实现图的DFS,BFS算法、最小生成树的普利姆算法和克鲁斯卡尔算法。

1.3最小生成树的需求与应用

对于n个顶点的连通网可以构建许多不同的生成树。

寻找最小生成树是连通网的造价最少。

假设要在n个城市之间建立通讯联络网,在每两个城市之间都可以设置一条线路,相应地都要付出一定的经济代价n个城市之间,最多可能设置n(n-1)\2条线路。

用连通网表示各城市及其间可能设置的通信路线,网的顶点表城市,边表城市间线路,赋予边上的权值表相应的代价。

通过最小生成树实现造价最小。

2.设计方案

2.1总体设计流程

1、先任意创建一个无向图。

2、根据所建无向图的结点数n,构造邻接矩阵。

3、用图的邻接表存储。

4、实现代码文件的译码。

2.2软件结构设计:

图2-1软件结构设计

表2-2函数返回类型

函数名

返回值类型

creatMGraph_L(G)

Int

creatadj(gra,G)

Int

ljjzprint(G)

Void

adjprint(gra,G)

Void

BFSTraverse(gra)

Void

DFStra(gra)

Int

MiniSpanTree_PRIM(g,G.vexnum)

Int

MiniSpanTREE_KRUSCAL(G,gra)

Void

 

2.3函数程序流程图

图2-4图的邻接表存储

图2-3图的邻接矩阵存储

3.方案实施

3.1图的遍历邻接矩阵的实现

根据所建无向图的结点数n,建立n*n的矩阵,其中元素全是无穷大(int_max),再将边的信息存到数组中。

其中无权图的边用1表示,无边用0表示;有全图的边为权值表示,无边用∞表示。

3.2图的遍历邻接表的存储

将信息通过邻接矩阵转换到邻接表中,即将邻接矩阵的每一行都转成链表的形式将有边的结点进行存储。

4.结果与结论

4.1源程序代码概要

1.定义程序中所有用到的数据及其数据结构,及其基本操作的实现;

邻接矩阵定义:

typedefstructArcCell

{

VRTypeadj;//VRType是顶点关系类型。

对无权图,用1或0表示相邻否;

对带权图,则为权值类型

InfoType*info;//该弧相关信息的指针

}ArcCell,AdjMatrix[max][max];

typedefstruct

{

VertexTypevexs[max];//顶点向量

AdjMatrixarcs;//邻接矩阵

intvexnum,arcnum;//图的当前顶点数和弧数

}MGraph_L;

邻接表的定义:

typedefstructArcNode//弧结点

{

intadjvex;//该弧指向的顶点的位置

structArcNode*nextarc;//指向下一条弧的指针

InfoType*info;//该弧相关信息的指针

}ArcNode;

typedefstructVNode//邻接链表顶点头接点

{

VertexTypedata;//顶点信息

ArcNode*firstarc;//指向第一条依附该顶点的弧的指针

}VNode,AdjList;

typedefstruct//图的定义

{

AdjListvertices[max];

intvexnum,arcnum;//图的当前顶点数和弧数

}ALGraph;

队列定义:

typedefstructQNode

{

QElemTypedata;

structQNode*next;

}QNode,*QueuePtr;

typedefstruct

{

QueuePtrfront;//队头指针

QueuePtrrear;//队尾指针

}LinkQueue;

4.2主函数和其他函数的伪码算法

主函数:

intmain()

{

ints;

chary='y’;

cout<<"创建一个无向图:

"<

MGraph_LG;

creatMGraph_L(G);

ALGraphgra;

creatadj(gra,G);

cout<<"||********************菜单*********************||"<

cout<<"||-------------------------【1、显示该图的邻接矩阵--------------------------||"<

cout<<"||-------------------------【2、显示该图的邻接表----------------------------||"<

cout<<"||-------------------------【3、广度优先遍历--------------------------------||"<

cout<<"||-------------------------【4、深度优先遍历--------------------------------||"<

cout<<"||-------------------------【5、最小生成树MiniSpanTree_PRIM算法-------------||"<

cout<<"||-------------------------【6、最小生成树MiniSpanTree_KRUSCAL算法----------||"<

cout<<"||************************************************************************

**||"<

while(y=='y')

{

cout<<"请选择菜单:

"<

cin>>s;

switch(s)

{

case1:

cout<<"邻接矩阵显示如下:

"<

ljjzprint(G);

break;

case2:

cout<<"邻接表显示如下:

"<

adjprint(gra,G);

break;

case3:

cout<<"广度优先遍历:

";

BFSTraverse(gra);

cout<

break;

case4:

cout<<"深度优先遍历:

";

DFStra(gra);

cout<

break;

case5:

if(n==0){cout<<"无权图没有最小生成树";break;}

elseif(l>0){cout<<"最小生成树不存在"<

else

{

inti,g[max][max];

for(i=0;i!

=G.vexnum;++i)

for(intj=0;j!

=G.vexnum;++j)

g[i+1][j+1]=G.arcs[i][j].adj;

cout<<"普利姆算法:

"<

MiniSpanTree_PRIM(g,G.vexnum);

break;

}

case6:

if(n==0){cout<<"无权图没有最小生成树";break;}

elseif(l>0){cout<<"最小生成树不存在"<

else

{

cout<<"克鲁斯卡尔算法:

"<

MiniSpanTREE_KRUSCAL(G,gra);

break;

}

return0;

}

邻接矩阵存储:

intcreatMGraph_L(MGraph_L&G)//创建图用邻接矩阵表示

{

charv1,v2;

inti,j,w;

cout<<"请输入顶点和弧的个数"<

cin>>G.vexnum>>G.arcnum;

cout<<"输入各个顶点"<

for(i=0;i

{

cin>>G.vexs[i];

}

for(i=0;i

for(j=0;j

{

G.arcs[i][j].adj=int_max;

G.arcs[i][j].info=NULL;

}

for(intk=0;k

{

cout<<"输入一条边依附的顶点和权"<

cin>>v1>>v2>>w;//输入一条边依附的两点及权值

i=localvex(G,v1);//确定顶点V1和V2在图中的位置

j=localvex(G,v2);

G.arcs[i][j].adj=w;

G.arcs[j][i].adj=w;

}

for(i=0;i!

=G.vexnum;++i)

for(j=0;j!

=G.vexnum;++j)

{

if(G.arcs[i][j].adj!

=1&&G.arcs[i][j].adj

}

if(n>=1)cout<<"这是一个有权图"<

elsecout<<"这是一个无权图"<

cout<<"图G邻接矩阵创建成功!

"<

returnG.vexnum;

}

邻接矩阵的输出:

voidljjzprint(MGraph_LG)//邻接矩阵的输出

{

inti,j;

if(n==0)

{

for(i=0;i!

=G.vexnum;++i)

{

for(j=0;j!

=G.vexnum;++j)

{

if(G.arcs[i][j].adj==int_max){cout<<"0"<<"";}

else{cout<

}

cout<

}

}

else

{

for(i=0;i!

=G.vexnum;++i)

{

for(j=0;j!

=G.vexnum;++j)

{

if(G.arcs[i][j].adj==int_max){cout<<"∞"<<"";}

else{cout<

}

cout<

}

}

}

用邻接表存储图:

intcreatadj(ALGraph&gra,MGraph_LG)//用邻接表存储图

{

inti=0,j=0;

ArcNode*arc;//,*tem,*p;

for(i=0;i!

=G.vexnum;++i)

{

gra.vertices[i].data=G.vexs[i];

gra.vertices[i].firstarc=NULL;

}

for(i=0;i!

=G.vexnum;++i)

for(j=0;j!

=G.vexnum;++j)

{

if(G.arcs[i][j].adj!

=int_max)

{

arc=(ArcNode*)malloc(sizeof(ArcNode));

arc->adjvex=j;

arc->nextarc=gra.vertices[i].firstarc;

gra.vertices[i].firstarc=arc;

}

}

gra.vexnum=G.vexnum;

gra.arcnum=G.arcnum;

cout<<"图G邻接表创建成功!

"<

return1;

}

邻接表输出:

voidadjprint(ALGraphgra,MGraph_LG)//邻接表输出

{

inti;

for(i=0;i!

=gra.vexnum;++i)

{

ArcNode*p;

cout<<"["<

p=gra.vertices[i].firstarc;

while(p!

=NULL)

{

cout<<"->"<<"["<adjvex<<"]";

p=p->nextarc;

}

cout<<"->"<<"End";

cout<

}

}

初始化队列:

StatusInitQueue(LinkQueue&Q)//初始化队列

{

Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));

if(!

Q.front)return0;//存储分配失败

Q.front->next=NULL;

return1;

}

入队:

StatusEnQueue(LinkQueue&Q,QElemTypee)//入队,插入元素e为Q的新的队尾元素

{

QueuePtrp;

p=(QueuePtr)malloc(sizeof(QNode));

if(!

p)return0;//存储分配失败

p->data=e;p->next=NULL;

Q.rear->next=p;Q.rear=p;

return1;

}

出队:

StatusDeQueue(LinkQueue&Q,QElemType&e)//出队,若队列不空,则删除Q的队头元素,用e返回,并返回真,否则假

{

QueuePtrp;

if(Q.front==Q.rear)return0;

p=Q.front->next;

e=p->data;

Q.front->next=p->next;

if(Q.rear==p)Q.rear=Q.front;

free(p);

return1;

}

判断队为空:

StatusQueueEmpty(LinkQueueQ)//判断队为空

{

if(Q.front==Q.rear)return1;

return0;

}

4.3程序运行结果

(1)创建一个无向图

图3-1创建一个无向图

(2)选择菜单运行

图3-2输出无向图

4.4课程设计总结

在做这个程序的时候你首先必须知道图的一些概念,图是一种较线性表和树更为复杂的数据结构。

在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。

当我们拿到一个图时,我们对该图的遍历就要有一些方法,所以有了深度优先遍历和广度优先遍历,我们要明白这两种遍历是怎么实现的,然后根据我们人脑中的方法把它写成电脑算法。

求图的最小生成树有两种算法,普利姆是从结点出发寻找权最小的边,知道所有结点都练通了;而克鲁斯卡尔算法则是从边出发,寻找使图连通的权值最小边的方法。

算法的实现从人脑到电脑的转变是比较复杂的一件事,要求做到具体到实现该方法的每一个步骤,然后再将每一个步骤通过代码实现。

这要求我们要明确各个数据元素和个元素之间的关系,然后才能明确使用算法去调用这些数据。

5.收获与致谢

通过本次的课程设计,我对数据结构有了一定的认识,明白了数据结构中数据,数据关系,及对其操作的方法。

但同时也发现在自己有很多的不足,在使用语言和如何精炼语言需要进行更多的训练。

总的来说,在整个设计的过程中,对文件的知识有了相当程度的了解掌握,基本上学会了对文件的设计和对文件的操作等。

在对文件的自学过程中也认识,在学习的过程中要灵活的把所学的知识运用到实践当中,并且还要巩固练习和运用,这样才可以牢牢的记住。

试验也对数据结构的知识进行了复习,尤其是在对程序不断的修改和逐步改进提升的过程中,积累了不少经验,为在以后的学习和实践应用奠定了一定的基础。

6.参考文献

[1]C语言程序设计(潭浩强第二版,清华大学出版社);

[2]数据结构(严蔚敏、吴伟民C语言版,清华大学出版社);

[3]数据结构实验教程(高晓兵等,清华大学出版社);

[4]钱能.C++程序设计教程第二版.北京:

清华大学出版社.2005;

[5]李兰,刘天印.C++程序设计实验指导.北京:

北京大学出版社.2006。

7.附件

附源程序清单电子档一份

 

指导教师评语:

1、课程设计报告:

a、内容:

不完整□完整□详细□

b、方案设计:

较差□合理□非常合理□

c、实现:

未实现□部分实现□全部实现□

d、文档格式:

不规范□基本规范□规范□

2、出勤:

全勤□缺勤次

3、答辩:

a、未能完全理解题目,答辩情况较差□

b、部分理解题目,部分问题回答正确□

c、理解题目较清楚,问题回答基本正确□

d、理解题目透彻,问题回答流利□

课程设计报告成绩:

,占总成绩比例:

50%

课程设计其它环节成绩:

环节名称:

出勤,成绩:

,占总成绩比例:

20%

环节名称:

答辩,成绩:

,占总成绩比例:

30%

总成绩:

指导教师签字:

年月日

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

当前位置:首页 > 高中教育 > 初中教育

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

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