数据结构实验一图剖析.docx

上传人:b****1 文档编号:734234 上传时间:2023-04-29 格式:DOCX 页数:20 大小:512.87KB
下载 相关 举报
数据结构实验一图剖析.docx_第1页
第1页 / 共20页
数据结构实验一图剖析.docx_第2页
第2页 / 共20页
数据结构实验一图剖析.docx_第3页
第3页 / 共20页
数据结构实验一图剖析.docx_第4页
第4页 / 共20页
数据结构实验一图剖析.docx_第5页
第5页 / 共20页
数据结构实验一图剖析.docx_第6页
第6页 / 共20页
数据结构实验一图剖析.docx_第7页
第7页 / 共20页
数据结构实验一图剖析.docx_第8页
第8页 / 共20页
数据结构实验一图剖析.docx_第9页
第9页 / 共20页
数据结构实验一图剖析.docx_第10页
第10页 / 共20页
数据结构实验一图剖析.docx_第11页
第11页 / 共20页
数据结构实验一图剖析.docx_第12页
第12页 / 共20页
数据结构实验一图剖析.docx_第13页
第13页 / 共20页
数据结构实验一图剖析.docx_第14页
第14页 / 共20页
数据结构实验一图剖析.docx_第15页
第15页 / 共20页
数据结构实验一图剖析.docx_第16页
第16页 / 共20页
数据结构实验一图剖析.docx_第17页
第17页 / 共20页
数据结构实验一图剖析.docx_第18页
第18页 / 共20页
数据结构实验一图剖析.docx_第19页
第19页 / 共20页
数据结构实验一图剖析.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

数据结构实验一图剖析.docx

《数据结构实验一图剖析.docx》由会员分享,可在线阅读,更多相关《数据结构实验一图剖析.docx(20页珍藏版)》请在冰点文库上搜索。

数据结构实验一图剖析.docx

数据结构实验一图剖析

数据结构实验报告

实验名称:

实验二——图

学生姓名:

佘晨阳

班级:

2014211117

班内序号:

20

学号:

2014210491

日期:

2015年12月05日

1.实验要求

根据图的抽象数据类型的定义,使用邻接矩阵或邻接表实现一个图。

图的基本功能:

1、图的建立

2、图的销毁

3、深度优先遍历图

4、广度优先遍历图

5、使用普里姆算法生成最小生成树

6、使用克鲁斯卡尔算法生成最小生成树

7、求指定顶点到其他各顶点的最短路径

8、其他:

比如连通性判断等自定义操作

编写测试main()函数测试图的正确性

2.程序分析

本实验要求掌握图基本操作的实现方法,了解最小生成树的思想和相关概念,了解最短路径的思想和相关概念,学习使用图解决实际问题的能力。

2.1存储结构

存储结构:

1.不带权值的无向图邻接矩阵

2.带权值的无向图邻接矩阵

3.带权值的有向图邻接矩阵

1.不带权值的无向图邻接矩阵

2带权值的无向图邻接矩阵.

3.带权值的有向图邻接矩阵

[备注]:

1.在使用打印元素、BFS、DFS采用无权值的无向图邻接矩阵存储方式

2.在使用PRIM、KRUSKAL、

3.在使用最短路径的算法时采用具有权值的有向图邻接矩阵存储方式

2.2关键算法分析

一.图的邻接矩阵构造函数:

1.关键算法:

template

Graph:

:

Graph(fa[],intn,inte)//带权值的图的构造函数

{

inti,j,k,height;

fs1,s2;

vnum=n;

arcnum=e;

for(k=0;k

for(k=0;k

{

for(i=0;i

{

arc[k][i]=-1;

if(i==k)arc[k][i]=0;//初始化权值的大小

}

visited[k]=0;

}

cout<

for(k=0;k

{

cout<<"请输入线性链接节点:

";

cin>>s1>>s2>>height;

arc[convert(s1)][convert(s2)]=height;

arc[convert(s2)][convert(s1)]=arc[convert(s1)][convert(s2)];//采用无向图带权值的邻接矩阵

}

cout<

cout<<"所得邻接矩阵为:

"<

for(k=0;k

{

for(i=0;i

{

if(arc[k][i]==-1)

cout<<"∞"<<"";

elsecout<

}

cout<

}

cout<

2.算法的时间复杂度

有构造可知,初始化时其时间复杂度:

O(n2)

二.深度优先便利DFS:

1.关键算法

①从某顶点v出发并访问

②访问v的第一个未访问的邻接点w,

访问w的第一个未访问的邻接点u,

……

③若当前顶点的所有邻接点都被访问过,则回溯,从上一级顶点的下一个未访问过的顶点开始深度优先遍历

④直到所有和v路径相通的顶点都被访问到;

2.代码图解:

深度优先遍历示意图

3.代码详解:

template

voidGraph:

:

DFS(intv)

{

cout<

visited[v]=1;

for(intj=0;j

if((visited[j]==0)&&(arc[v][j]>=1))DFS(j);//当存在回路时,则连通深一层遍历

}

4.时间复杂度

时间复杂度:

O(n2)

空间复杂度:

栈的深度O(n)

辅助空间O(n)

三.广度遍历BFS

1.关键算法

①访问顶点v

②依次访问v的所有未被访问的邻接点v1,v2,v3…

③分别从v1,v2,v3…出发依次访问它们未被访问的邻接点

④反复①②③,直到所有和v路径相通的顶点都被访问到;

2.代码图解

3.代码详解

1.初始化队列Q

2.访问顶点v,visited[v]=1

3.while(队列非空)

3.1v=队头元素出队

3.2访问队头元素的所有未访问的邻接点

4.时间复杂度

时间复杂度:

O(n2)

空间复杂度:

辅助空间O(n)

四.最小生成树——普里姆算法

1,关键思路

一般情况下,假设n个顶点分成两个集合:

U(包含已落在生成树上的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边。

主数据结构:

邻接矩阵

辅助数据结构:

intadjvex[MAXSIZE];//U集中的顶点序号

intlowcost[MAXSIZE];//Uà(V-U)的最小权值边

2.代码图解

3;代码详解

template

voidGraph:

:

Prim()

{

for(inti=0;i

{

adjvex[i]=0;lowcost[i]=arc[0][i];

}

lowcost[0]=0;

for(intj=1;j

{

intk=Mininum(lowcost);//求下一个顶点

cout<"<

lowcost[k]=0;//U=U+{Vk}

for(intj=0;j

{

if((lowcost[j]!

=0&&arc[k][j]

{

lowcost[j]=arc[k][j];

adjvex[j]=k;

}

}

}

}

4,时间复杂度:

时间复杂度O(n2),适合稠密图

五.最小生成树----克鲁斯卡尔算法

1,关键思路

先构造一个只含n个顶点的子图SG,然后从权值最小的边开始,若它的添加不使SG中产生回路,则在SG上加上这条边,如此重复,直至加上n-1条边为止。

2.代码图解:

3.代码详解

template

voidGraph:

:

Kruskal()//最小生成树—kruskal算法

{

cout<<"Krusal算法结果为:

"<

intvset[MAXSIZE];

for(inti=0;i

intk=0,j=0;

while(k

{

intm=vedgelist[j].fromv,n=vedgelist[j].endv;

intsn1=vset[m];

intsn2=vset[n];//两个顶点分属不同的集合

if(sn1!

=sn2)

{

cout<"<

k++;

for(inti=0;i

{

if(vset[i]==sn2)

vset[i]=sn1;//集合sn2全部改成sn1

}

}

j++;

}

}

4.时间复杂度

时间复杂度O(nlogn),适合稀疏图

六.最短路径——Dijkstra算法

1.关键代码

•按路径长度递增的次序产生源点到其余各顶点的最短路径。

•1)设置集合s存储已求得的最短路径的顶点,

•2)初始状态:

s=源点v

•3)叠代算法:

•直接与v相连的最近顶点vi,加入s

•从v经过vi可以到达的顶点中最短的,加入s

……

2.代码图解

3.代码详解

emplate

voidGraph:

:

ShotPath(fx)//关于最短路径的初始化

{

intv=convert(x);

for(inti=0;i

{

s[i]=0;

disk[i]=arc[v][i];

if(disk[i]!

=maxs)path[i]=v;

elsepath[i]=-1;

}

s[v]=1;disk[v]=0;

path[v]=-1;

for(inti=0;i

{

if((v=FindMin())==-1)continue;

s[v]=1;

for(intj=0;j

if(!

s[j]&&(disk[j]>arc[v][j]+disk[v]))

{

disk[j]=arc[v][j]+disk[v];

path[j]=v;

}

}

Print();//打印路径长度和遍历

}

4.时间复杂度

时间复杂度为:

n^2

七.判断连通图算法

template

boolGraph:

:

judgegraph()

{

DFS(convert(vertex[0]));

if(count==vnum)

{

cout<<"该图为连通图!

*******输入成功!

"<

returnfalse;

}

else

{

cout<<"该图不为连通图!

*******请重新输入"<

returntrue;

}

}

时间复杂度:

n^2

3.程序运行结果

1.测试主函数流程:

函数流程图:

1.输入图的连接边并打印

构造下面所示图的邻接矩阵:

2.判断图连通是否成功

3.BFSDFSPRIM算法的实现

4.克鲁斯卡尔算法实现过程

4.有向图邻接矩阵的构建

插入V0位置后打印距离并开始回溯

总结

1.调试时出现的问题及解决的方法

问题一:

prim算法中

解决方法:

调整循环条件,修正函数体注意有无Next的区别

问题二:

BFS和DFS同时在一个类里作用时会输出错误

解决方案:

每次BFS/DFS使用时都把visited数组初始化一遍

问题三:

在最短路径,经常出现了停止输入的情况

解决方法:

改return为continue,并修改打印算法

2.心得体会

通过本次实验,基本熟练掌握了c++基本语句,尤其对图的结构及应用有了较深了解;调试代码时尽量做到完成一个代码段调试一次,可以最快检测出错误所在;类的封装和调用,类的共有成员和私有成员的设置。

3.下一步的改进

第一,设置增加图节点和边的函数

第二,实现图形化输出图的路径的功能

第三,主函数设计简单,不要过于累赘

4.程序中出现的亮点

1)利用dfs算法衍生生成判断是否为连通图的连通算法

2)采用graph类实现所有图的所有算法,所需的数据类型均在私有成员内,封装

3)利用convert函数采取象意输入,采用ABCD的节点输入方式而并非转化成01234再输入。

4)BFS中采用c++标准库的。

5)打印邻接矩阵时,打印出非链接的∞符号和与自身路径的0距离

6)判断图为非连通图后,提示输入错误,重新输入图元素

 

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

当前位置:首页 > 临时分类 > 批量上传

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2