20182303 2019-2020-1 《数据结构与面向对象程序设计》实验9报告
课程:《程序设计与数据结构》
班级: 1823
姓名:张端云
学号:20182303
实验教师:王志强
实验日期:2019年12月2日
必修/选修: 必修
1.实验内容
图的综合实践
(1) 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分)
(2) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分)
(3) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分)
(4) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分)
(5) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分)
2. 实验过程及结果
point1
初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义。
输入1为无向图,输入2为有向图
if(Direct==1)
{
int vexNum = 0;
int arcNum = 0;
while(true) {
System.out.print("请输入要建立无向图的总顶点数和总边数,以空格隔开:");
try {
vexNum = scan.nextInt();
arcNum = scan.nextInt();
break;
} catch (Exception e) {
System.out.println("输入不合法!");
continue;
}
}
UnGraph aMGraph = new UnGraph(vexNum, arcNum);
System.out.println("由深度优先遍历得:");
aMGraph.dFSTraverse();
System.out.println("由广度优先遍历得:");
aMGraph.bFSTraverse();
scan.close();
}
else if(Direct==2)
{
DirGraph.Dirgraph a = new DirGraph.Dirgraph(6);
a.addEdge(0, 1);
a.addEdge(0, 3);
a.addEdge(1, 2);
a.addEdge(2, 5);
a.addEdge(3, 2);
a.addEdge(4, 3);
a.addEdge(4, 2);
System.out.println(a);
DirGraph.DirectedDFS dfsa = new DirGraph.DirectedDFS(a);
//第一种方法检查环
System.out.println("是否存在环?");
System.out.println(dfsa.hasCycle());
System.out.println();
System.out.println("拓扑排序序列:");
for (Integer integer : dfsa.Topological()) {
System.out.print(integer + " ");
}
System.out.println("\n由深度优先遍历得:");
dfsa.DFS(0);
System.out.println("由广度优先遍历得:");
DirGraph.BFS bfsa=new DirGraph.BFS(a);
bfsa.bfs(0);
}
}
在前面我们所介绍的树的数据结构中,我们可以明显感觉到,树的表示是分层的,例如父子关系,而其他关系只能间接的表示,例如同级关系。而图却不受这种限制。图是由顶点(或结点)及顶点之间的关系组成的集合。通常,图中的顶点数量或者一个顶点与其他顶点之间的连线的个数不受限制。(C++数据结构与算法)
无向图
由一组顶点和一组能够将两个顶点相连的边组成的。
有向图
由一组顶点和一组有方向的边组成,每条有方向的边都连接着有序的一对顶点。
point2
图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)
- 深度优先遍历的思路是:
先将起始顶点入栈--->获取栈顶元素作为当前正在遍历的元素--->获得当前正在遍历的元素的邻接表--->找出它的邻接表中还未被访问的一个顶点--->访问该顶点(将该顶点保存到访问路径中),并将该顶点压栈
如果当前正在遍历的元素的邻接表为空或者该顶点的所有邻接表中的顶点都已经访问了,说明需要回退了。因此,弹出栈顶元素。 - 广度优先遍历算法:我们先遍历开始结点的相邻结点并将结点,然后按照与起点的距离的顺序来遍历所有的顶点。在广度优先遍历中,将使用队列(FIFO)来保存结点。
进行广度优先遍历的算法步骤如下:
先将起点加入队列,然后重复以下步骤:
取队列中的下一个顶点v并标记它
将与v相邻的所有未被标记过的结点加入队列
point3
完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环
point4
完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出
此处选用了Prim算法
point5
完成有向图的单源最短路径求解(迪杰斯特拉算法)
代码托管
3. 实验过程中遇到的问题和解决过程
- 问题1:什么是
HashMap
? - 问题1解决方案:许多博主在定义图时,都会使用
HashMap
。
Map<String, ArrayList<String>> graph = new HashMap<String, ArrayList<String>>(arr.length);//根据字符串数组arr构造图
for (String str : arr) {
graph.put(str, new ArrayList<String>());
}
HashMap在JDK1.8之前的实现方式 数组+链表,但是在JDK1.8后对HashMap进行了底层优化,改为了由 数组+链表+红黑树实现,主要的目的是提高查找效率。具体参考数据结构解析-HashMap.
参考资料
原文地址:https://www.cnblogs.com/zdyyy/p/12007484.html