20202307 实验九《图》实验报告
20202307 2021-2022-1 《数据结构与面向对象程序设计》实验九报告
课程:《程序设计与数据结构》
班级: 2023
姓名: 范宇涵
学号:20202307
实验教师:王志强
实验日期:2021年12月21日
必修/选修: 必修
实验内容
- 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)
- 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
- 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
- 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
- 完成有向图的单源最短路径求解(迪杰斯特拉算法)
实验过程及结果
初始化
-
自定义图分别如下图所示:
-
设置输入1时输出无向图1的邻接矩阵 输入2对应输出有向图2的邻接表
https://gitee.com/besti2023javads/fan-yuhan-20202307/tree/master/src/Graph
图的遍历
深度优先遍历(DFS)
- 将起始顶点入栈,获取栈顶元素作为当前正在遍历的元素
- 获得当前正在遍历的元素的邻接表
- 找出它的邻接表中还未被访问的一个顶点
- 访问该顶点(即将该顶点保存到访问路径中),并将该顶点压栈
- 当正在遍历的元素的邻接表为空或该顶点的所有邻接表中的顶点都已经被访问,弹出栈顶元素
广度优先遍历(BFS)
- 访问顶点v,并将其标记为已经访问过
- 从v的未被访问的邻接点中选取一个顶点w,从w出发进行深度优先遍历
- 重复上述两步,直至图中所有与v存在路径相通的顶点都被访问到
拓补排序
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/Graph.java
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/DiGraph.java
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/UndiGraph.java
最小生成树
Prim算法——从点入手
- 建立候选边集表,把从起始点u0出发到其余各点的权值记录在其中,开始令u=u0
- 在候选边集中选择结点u
- 在候选边集中选出最短边(u, v);
- 以v为起点,调整候选边集:
当(u, x)>(v, x)时,用(v, x)替换(u, x),x为除u、v外的其他点 - 重复上述步骤直至所有结点都处理完毕。
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/Prim.java
Kruskal算法——从边出发
- 遍历后按照权值大小对所有的边进行排序
- 找出其中权值最小的边
- 递归重复上述步骤,直至找出n-1条边(n为图的顶点数)
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/Kruskal.java
Dijkstra算法
https://gitee.com/besti2023javads/fan-yuhan-20202307/blob/master/src/Exp9/Dijkstra.java
其他(感悟、思考等)
课堂上的知识讲解让我对图的存储结构、遍历、求最小生成树等问题有了比较清晰的认识,但真正实验通过代码实现这一步仍然遇到了不小的困难与挑战,简直“一步一个坎儿”。虽然初步掌握了数据结构,但在java语言程序设计这条路上,我显然还有很长的路要走。不过在编写、改造代码的过程中,通过钻研课本和网页资料,对数据结构透彻剖析之后,我对图这种结构也有了较为深刻的认知,并能简易应用。