20172325 2018-2019-2 《Java程序设计》第九周学习总结

教材学习内容总结

图的定义

  • 图是由顶点集(VertexSet)和边集(EdgeSet)组成,针对图G,顶点集和边集分别记为V(G)和E(G)。依据图的边集是否为有向,可把图分为有向图和无向图,根据图是否有权重,可以分为有权图和无权图。
  • 图的基本术语:

    1.邻接点----在一个无向图中,若存在一条边(Vi,Vj),则称Vi,Vj为此边的两个端点,并称它们互为邻接点;

    2.出/入边 -----在一个有向图张,若存在一条边<Vi,Vj>,则称此边为顶点Vi的出边,顶点Vj的一条入边;

    3.度/入度/出度----无向图中的度定义为以该顶点为一个端点的边的数目,记为D(V)。有向图的入度定义为多少边指向该顶点,出度是该顶点出边的个数;
  • 根据边是否有方向,将图可以划分为:无向图和有向图。
  • 无向图:

  • 有向图:

网络

网络或称为加权图,是一种每条边都带有权重或代价的图,加权图中的路径权重是该路径中各条边权重的和。

对于网络,我们将用一个三元组来表示每条边,这个三元组中包括起始顶点、终止顶点和权重。对于无向网络来说,起始顶点与终止顶点可以互换。

最小生成树

对于图的操作,还有一个最常用的就是找到最小生成树,最小生成树就是用最少的边连接所有顶点。对于给定的一组顶点,可能有很多种最小生成树,但是最小生成树的边的数量 E 总是比顶点 V 的数量小1,即:

  V = E + 1

这里不用关心边的长度,不是找最短的路径(会在带权图中讲解),而是找最少数量的边,可以基于深度优先搜索和广度优先搜索来实现。

比如基于深度优先搜索,我们记录走过的边,就可以创建一个最小生成树。因为DFS 访问所有顶点,但只访问一次,它绝对不会两次访问同一个顶点,但她看到某条边将到达一个已访问的顶点,它就不会走这条边,它从来不遍历那些不可能的边,因此,DFS 算法走过整个图的路径必定是最小生成树。

图的遍历

图的遍历包括深度优先和广度优先搜索

(关于遍历,参考到其他博客,点击此处查看原文)

深度优先搜索

思路:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。显然,深度优先搜索是一个递归的过程。

无向图深度优先搜索图解:



有向图深度优先搜索图解:

广度优先搜索

   从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远。

无向图广度优先搜索图解:



有向图广度优先搜索图解:

图的java实现

  • 有两种:二维数组表示(邻接矩阵);链表表示(邻接表)。

  • 邻接矩阵,是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是的row和col表示的是1....n个点。对于无向图 如果顶点b1和b2是连接的,那么在二维矩阵中matrix[b1,b2]和matrix[b2,b1]位置的值置为1,如果是有向图b1指向b2,那么 matrix[b1,b2]=1,matrix[b2,b1]=0;下面用一个例子表示无向图和有向图的邻接矩阵;

邻接矩阵以矩阵的形式存储图所有顶点间的关系。邻接矩阵具有以下特点:

  • 1,邻接矩阵是正矩阵,即横纵维数相等。

  • 2,矩阵的每一行或一列代表一个顶点,行与列的交点对应这两个顶点的边。

  • 3,矩阵的点代表边的属性,1代表有边,0代表无边,所以矩阵的对角线都是0,因为对角线上对应的横纵轴代表相同的顶点,边没有意义。

  • 4,如果是无向图,那么矩阵是对称矩阵;如果是有向图则不一定。

  • 5,如果是有权图,矩阵点数值可以是权值。

  • 6,邻接矩阵表示图的关系非常清晰,但消耗空间较大。

  • 邻接矩阵与邻接表相比,它会造成空间的一定损失,它需要为每个顶点都分配n个边的空间,其实有很多边都是不存在边,但是邻接表的实现就不一样,它只关心存在的边,不关心不存在的边。

邻接表是以一组链表来表示顶点间关系,有以下特点:

  • 1,邻接表示一个有但链表组成的数组
  • 2,图中的每一个顶点都有一个链,数组的大小等于图中顶点的个数。
  • 3,无向图的链的第一个元素是本顶点,后继分别连接着和这个顶点相连的顶点;有向图的链第一个顶点是本顶点,后继是以本顶点为起点的边的终点。
  • 4,如果是有权图,可以在节点元素中设置权值属性
  • 5,邻接链表关系表示不如邻接矩阵清晰,数据结构相对复杂,但节省空间。

邻接表由数组+链表组成对于上面的无向图,邻接表表示为(由于有向和无向的差别不是太大,所以只是画出了无向的邻接表表示):



该图标是为,标号为0的结点的相关联的结点为 1 2 3 4;标号为1的结点的相关联结点为0 4,标号为2的结点相关联的结点为 0 4 5......

教材学习中的问题和解决过程

教材学习有问题先去https://shimo.im/doc/1i1gldfsojIFH8Ip/看看,如果别人没有提出相同问题,可以编辑文档添加,然后把自己提出的问题复制到下面:

  • 问题1:看完教材之后不太明白如何获取某顶点所有相连接的点。

  • 问题1解决方案:顶点类里面 使用了一个私有的内部类实现了一个邻接点的迭代器,

/**Task: 遍历该顶点邻接点的迭代器--为 getNeighborInterator()方法 提供迭代器
* 由于顶点的邻接点以边的形式存储在java.util.List中,因此借助List的迭代器来实现
* 由于顶点的邻接点由Edge类封装起来了--见Edge.java的定义的第一个属性
* 因此,首先获得遍历Edge对象的迭代器,再根据获得的Edge对象解析出邻接点对象
*/
private class NeighborIterator implements Iterator<VertexInterface<T>>{ Iterator<Edge> edgesIterator;
private NeighborIterator() {
edgesIterator = edgeList.iterator();//获得遍历edgesList 的迭代器
}

这个迭代器的作用就是用来遍历当前顶点对象(this)的邻接点的。

你只需要获得这个迭代器,就可以遍历该顶点的邻接点了。

代码调试中的问题和解决过程

  • 问题1:如何返回一个节点的所有邻居?
graph.addEdge("A", "D");
graph.addEdge("A", "C");
while(graph.getVertices().get("A").getNeighborInterator().hasNext())
{
System.out.println(graph.getVertices().get("A").getNeighborInterator().next().getLabel());
}

这里我添加了两条边<A,D>,<A,C>,利用迭代器将A的邻居节点的表示服打印出来是发现陷入死循环,一直打印第一个邻居D

  • 问题1解决方案:需要在源代码里面添加一个方法获取所有的顶点(当然,不要忘了在它实现的接口中添加方法的声明):

    public Map<T, VertexInterface> getVertices()

    {

    return vertices;

    }

然后就可以这样来访问某个顶点的邻接点了。

①创建图,添加顶点和边。②获取目标顶点。③获得目标顶点的迭代器。④拿着迭代器遍历该顶点的邻接点。

import java.util.Iterator;
import java.util.Map; public class TestGraphBlog { public static void main(String[] args) { GraphInterface<String> graph = new DirectedGraph<>();
//添加顶点
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
//添加边
graph.addEdge("A", "D");
graph.addEdge("A", "C"); Map<String, VertexInterface<String>> verttices = graph.getVertices();
VertexInterface<String> vertex_A = verttices.get("A");//获得顶点
Iterator<VertexInterface<String>> it = vertex_A.getNeighborInterator(); while(it.hasNext())
{
String vertex_Label = it.next().getLabel();
System.out.println(vertex_Label);
}
}
}

代码托管

(statistics.sh脚本的运行结果截图)

上周考试错题总结

暂无

结对及互评

  • 本周结对学习情况

    • 20172306
    • 结对学习内容
      • 学习了第十五章的内容
      • 编译书中代码
      • 编写课后的作业

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 200/200 2/2 20/20
第二周 300/500 2/4 18/38
第三周 500/1000 3/7 22/60
第四周 300/1300 2/9 30/90

参考资料

20172325 2018-2019-2 《Java程序设计》第九周学习总结的更多相关文章

  1. 201521123027 <java程序设计>第九周学习总结

    1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2.书面作业 Q1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什 ...

  2. 20145220java程序设计第九周学习总结

    20145220java程序设计第九周学习总结 教材学习内容总结 JBDC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商对接口直接操作,开发人员无须接触底层数据可驱动程序的差异 ...

  3. 201771010134杨其菊《面向对象程序设计java》第九周学习总结

                                                                      第九周学习总结 第一部分:理论知识 异常.断言和调试.日志 1.捕获 ...

  4. 201521044152<java程序设计>第一周学习总结

    本周学习总结 java开发时间虽然很短,但是发展迅速,已成为现在非常流行的一门语言,很开心能有幸学习java.第一周学习了java的平台,运行环境jdk以及jrt等等新名词,还了解了eclipse的基 ...

  5. 20145304 刘钦令 Java程序设计第二周学习总结

    20145304 <Java程序设计>第2周学习总结 教材学习内容总结 java可区分基本类型和类类型(即参考类型)两大类型系统. 基本类型主要可区分为整数.字节.浮点数.字符与布尔. 整 ...

  6. 20145304 刘钦令 Java程序设计第一周学习总结

    20145304<Java程序设计>第1周学习总结 教材学习内容总结 1995年5月23日,是公认的Java的诞生日,Java正式由Oak改名为Java. Java的三大平台是:Java ...

  7. 201621123007 Java程序设计第一周 学习总结

    第一周-Java基本概念 201621123007 <Java程序设计> 第一周学习总结 1. 本周学习总结 java是面向对象的一类语言,三大特征:封装性,继承性,多态性. jdk jr ...

  8. 马凯军201771010116《面向对象与程序设计Java》第九周学习总结

    一.理论知识部分 异常.日志.断言和调试 1.异常:在程序的执行过程中所发生的异常事件,它中断指令的正常执行. 2.Java的异常处理机制可以控制程序从错误产生的位置转移到能够进行错误处理的位置. 3 ...

  9. 201521123063 JAVA程序设计 第二周学习总结

    1.本周学习重点(2.27-3.5) java中的数组 以二维数组为例,数组名为scores,则 (1)先声明数组 int[][] scores;或int scores[][];或int[] scor ...

  10. 《Java》第九周学习总结

    下载mysql 选择mysql的管理软件 idea可以直接连接 然后用库运行程序,但是没有截图,,因为想在navicat上试试,可惜速度太慢了 打开idea又很慢,所以明天再更新

随机推荐

  1. Flume调优

    这是一个关于池子的故事.有一个池子,它一头进水,另一头出水,进水口可以配置各种管子,出水口也可以配置各种管子,可以有多个进水口.多个出水口.水术语称为Event,进水口术语称为Source.出水口术语 ...

  2. [zz] MATLAB工具箱介绍

    http://blog.sina.com.cn/s/blog_57235cc701012kfb.html Toolbox工具箱 序号 工具箱 备注   数学.统计与优化   1 Symbolic Ma ...

  3. 域名到站点的负载均衡技术一览(主要是探讨一台Nginx抵御大并发的解决方案)(转)https://www.cnblogs.com/EasonJim/p/7823410.html

    一.问题域 Nginx.LVS.Keepalived.F5.DNS轮询,往往讨论的是接入层的这样几个问题: 1)可用性:任何一台机器挂了,服务受不受影响 2)扩展性:能否通过增加机器,扩充系统的性能 ...

  4. STM32定时器时间的计算方法

    本文出自:https://wenku.baidu.com/view/e3bdfb7601f69e31433294c4.htmlSTM32定时器时间的计算方法STM32中的定时器有很多用法:(一)系统时 ...

  5. 过滤器手动注入Service Bean方法

    @Override public void init(FilterConfig arg0) throws ServletException { ServletContext servletContex ...

  6. Spring复习

    第一天 IOC:控制反转,对象的创建权交给Spring DI:依赖注入,前提必须有IOC的环境,Spring管理这个类的时候将类的依赖的属性注入(设置)进来. 包括集合的注入 ClassPathXml ...

  7. django模型系统(三)

    1,自定义主键字段的创建 AutoFiled(pirmary_key=True)  # 一般不会自定义 2,order_by  asc  desc 表关系 OneToOne student = mod ...

  8. doris 0.9.0版本docker镜像制作与使用

    1. 安装docker 详情请参见本人博客 2. 编译doris 详情请参见doris官网文档 3. 在编译好的doris output文件夹下编写两个Dockerfile 3.1  Dockerfi ...

  9. [sharepoint]Rest api相关知识(转)

    写在前面 最近又开始弄rest api了,通过sharepoint rest api获取站点信息,Items,fields非常方便,再结合OData查询,更是得心应手.这里记录学习的时候用到的知识点, ...

  10. centos7将可执行程序做成服务

    1.systemctl 用法:systemctl [OPT] COMMAND [NAME]…启动服务:systemctl start NAME.service停止服务:systemctl stop N ...