2018-2019-20172329 《Java软件结构与数据结构》第九周学习总结

2018-2019-20172329 《Java软件结构与数据结构》第九周学习总结

教材学习内容总结

《Java软件结构与数据结构》第十五章-图

1、图及无向图php

  • 一、图的相关概念:
    • (1)一个图(graph)G=(V,E)由顶点(vertex)的集V和边(edge)的集E组成。每一条边就是一幅点对(v,w)。
    • (2)若是点对是有序的,那么图就是有向的。
    • (3)假如点对是无序的,那么图就是无向的。
    • (4)若是图中的两个顶点之间有一条连通边,则称这两个顶点是衔接的。邻接顶点有时也称为邻居。连通一个顶点及其自身的边称为自循环或环。
    • (5)边的条数的计算:对于第一个顶点,须要(n-1)条边将其与其余顶点连通。而对于第2个顶点,只须要(n-2)条边,由于第二个顶点已经和第一个顶点连通了。第三个顶点须要(n-3)条边。继续向下,直到最后一个顶点,这个末顶点不须要额外的边,由于全部其余的顶点都已经和它连通了。1~n的求和是:求和(n+1)n/2。
    • (6)路径:路径是图中的一系列边,每条边连通两个顶点。
    • (7)路径的长度是该路径中边的条数(或者是顶点减去1)
  • 二、无向图:
    • (1)若是无向图拥有最大数目的连通顶点的边,则认为这个无向图是彻底的。
    • (2)若是无向图中的任意两个顶点之间都存在一条路径,则认为这个无向图是连通的。
    • (3)无向树是一种连通的无环无向图,其中一个元素被指定为树根。

2、有向图html

  • 一、有向图有时也称为双向图,它是一种边为有序顶点对的图。以下图:
  • 二、有向图中的路径是图中连通两个顶点的有向边序列。
    • (1)连通:
    • (2)没连通:
  • 三、拓扑序:
    • (1)拓扑排序是对有向无圈图的顶点的一种排序,使得存在一条从vi到vj的路径,那么在排序中vi的后面。
  • 四、有向图的属性:
    • (1)不存在其余顶点到树根的链接。
    • (2)每一个非树根元素刚好有一个链接。
    • (3)树根到每一个其余顶点都有一条路径。

3、网络java

  • 一、网络:或称为加权图,是一种每条边都带有权重或代价的图。
    • 加权图中的路径权重是该路径中各条边权重的和。
    • 对于网络咱们将用一个三元组来表示各条边。这三元组包括起始起点、终止顶点和权重。注:对于无向网络来讲,起始顶点和终止顶点能够互换。可是在有向图来讲,必须包含每一个右相链接的三元组。

4、经常使用的图算法web

  • 一、遍历

(1)广度优先遍历:算法

  • a、广度优先遍历相似于树的前序遍历;
  • b、能够用一个队列和一个无序列表来构造出结果;
  • c、步骤:
    • 一、起始顶点进入队列,同时标记该顶点为已访问的。
    • 二、而后开始循环,该循环一直持续到队列为空时中止,在这个循环中,从从队列中取出这个首顶点,并将它添加到列表的末端。
    • 三、接着让全部与当前顶点邻接且还没有被标记为已访问的各个顶点依次进入到队列,同时把他们逐个标记为已访问,而后重复上述循环。
    • 四、对每一个已访问的结点都重复这一过程,直到队列为空时结束,这意味着咱们没法再找到任何新的顶点。
    • 五、如今的链表即以广度优先遍历器。
  • d、遍历实例:从顶点9开始进行广度优先遍历的步骤以下(链接以下图)
    • 一、往队列中添加9,而且把它标记为已访问;编程

    • 二、从队列中取出9;数组

    • 三、往链表中添加9;网络

    • 四、从队列中添加六、七、8,逐个标记为已访问;数据结构

    • 五、从队列中取出6;学习

    • 六、往链表中添加6;

    • 七、往队列中添加三、4,逐个标记为已访问。

    • 八、从队列中取出7,并将它添加到链表中;

    • 九、往队列中添加5,而且把它标记为已访问;

    • 十、从队列中取出8,并将它添加到链表中(这时再也不往队列中添加任何新的结点了,由于顶点8再也没有还没有访问过的邻居了)

    • 十一、从队列中取出3,并将它添加到链表中;

    • 十二、往队列中添加1,而且把它标记为已访问;

    • 1三、从队列中取出4,并加它添加到列表中;

    • 1四、往队列中添加2,而且把它标记为已访问;

    • 1五、从队列中取出5,并将它添加到列表中(因为再没有未访问过的邻居,所以不需再往队列中添加顶点)

    • 1六、从队列中取出2,并将它添加到链表中;

    • 1七、从队列中取出2,并将它添加到列表中。

    • 这样列表就以广度优先次序存放了从顶点9开始的以下顶点:九、六、七、八、三、四、五、1和2.

  • 二、测试连通性
    • (1)定义:若是图中的任意两个顶点之间都存在一条路径,则认为这个图是连通的。
    • (2)该定义对无向图和有向图都是成立的。
    • (3)断定:在一个含n个顶点的图中,当且仅当对每一个顶点v,从v开始的广度优先遍历的列表大小都是n,则该图就是连通的。
    • 举例:
      以下图:

起始顶点 广度优先遍历
A A,B,C,D
B B,A,D,C
C C,B,A,D
D D,B,A,C
  • 三、最小生成树
  • (1)生成树是一颗含有图中全部顶点和部分边(但有可能不是全部边)的树。因为树也是图,所以对于某些树而言,其自己就是一颗生成树,这是该图的惟一辈子成树包含全部边。
  • 如图
起始顶点 广度优先遍历
A A,B,C
B B,A,C
C C,B,A
D D

  • (2)生成树的一个有趣应用是找出加权图的最小生成树。最小生成树,其边的权重其边的权重总和小于或等于同一个图中的其余任何一颗生成树的权重总和。
  • (3)算法介绍:Prim算法
    • 一、计算最小生成树的一种方法是使其连续地一步一步长成。在每一步,都要把一个结点看成根并往上加边。
    • 二、在算法的任意时刻,咱们均可以看到一组已经添加到树上的顶点,而其他顶点还没有加到这棵树中。此时算法在每一阶段均可以经过选择边(u,v)使得(u,v)的值是全部u在树上但v不在树上的边的值中的最小者而找到一个新的顶点并把它添加到这课树中。
    • 三、如图:

  • 四、判断最短路径
  • (1)判断图中的最短路径有两种状况:
    • 一、断定起始顶点与目标顶点之间的字面意义上的最短路径,也就是两个顶点之间的最小边树。
    • 二、寻找加权图的最便宜路径。
  • (2)第一种:从起始顶点到本顶点的路径长度,以以路径中做为本顶点前驱的那个顶点。接着要修改循环,使得当抵达目标顶点时循环将终止,最短路径的路径长度就是从起始顶点到目标顶点前驱顶点的路径长度再加1:若是要输出这条最短路径上的顶点,只需沿着前趋链回溯便可。
  • (3)第三个:新的一个算法:Dijkstra算法,我会在代码问题中详细进行描述。

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

  • 问题1:在教材308页中介绍有向图的时候有这样两句话:

有向图有时也称为双向图。

有向图中的路径并非双向的。

就这两句话,我产生了疑问,为何有向图不为双向,但叫作双向图,他所谓的双向是同样的吗?

  • 问题1解决方案:
    (1)由于就有向图自己而言,为的确能够为双向的,咱们能够在上述的教材内容总结中在网络一部分能够看到两张这样的图:

在第二张很显然就是一个双向的网络,网络一样也是图的一种,可是我很详细的看了一下有向图中的路径并非双向的。这句话出现的地方,这句话后买呢还接着一句话:除非咱们添加了额外的边连通他们俩,也就是这句话介绍是就假如A指向了B,可是在前提中就没有让B指向A,当咱们有指向返回的那条边的时候才能够有双向,因此我以为书本在这里写的会误导第一次学习有向图的同窗。

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

  • 问题1:pp15.7的具体以及我思考的整个过程?
  • 问题1解决方案:
    (1)这一周假如算看完书开始作pp项目以来,引得我三天茶不思饭不想的一道题就是这个pp15.7,既然将它写进这个调试,我以为须要好好记录一下这一周中三天是如何进行这道题的思考的。
    (2)其实这道题想一想并不难,它只是要求咱们求的最便宜路径的最便宜价格是多少,因此一开始个人第一个问题就是如何去保存这个咱们输入的权重。由于一开始真的是没有什么思路,就一直在纸上画,写各类各样的伪代码。
    (3)而后就忽然有了本身的初版想法:
  • 一、我在看到用邻接矩阵记录是否连通的这个数组有了契机,就以为这个二维数组是个好东西,就以为是它了。由于我就在添加边的方法中加了这样一句语句Weight[getIndex((T) vertex1)][getIndex((T) vertex2)]=weight;,用于对于权重添加到一个二位数组中,同时在无向图中是有与它对称的语句Weight[getIndex((T) vertex2)][getIndex((T) vertex1)]=weight;,这样就讲连起来的线给赋予一个权重。
  • 二、而后我写了这样的一个表格进行明晰

  • 三、而后我就想经过两个或三个循环进行找到T,而后用一个result记录下来,进行重复的找而后找到一条路走到尽头,将结果存进一个数组中,重复过程。个人初版代码以下
Double[] temp = new Double[100];
        Double result=0.0;
        int a =0;
        int b =0;
        int c=0;
        for (int i =0;i<end+1;i++){
            start=c;
            result=0.0;
            for (int j =b;j<end;j++) {
                result=0.0;
                start=a;
                for(int r=b;r<end;r++){
                    result += Weight[start][r + 1];
                    start=r+1;
                    }
                temp[a]=result;
                a++;
                b=b+2;
            }


            a++;
            b++;
        }
//我经过一直讲这个二维数组的位置进行查找在相加再保存
  • 四、而后将存进数组的元素找到最小的那个进行输出
Double min = temp[0];

            for (int r =0;r<end;r++){
                if (temp[r+1]<min&&temp[r+1]>0){
                    min=temp[r+1];
                }
            }

        return min;
  • 五、为何我会毙掉初版,由于存在着很大的问题,首先,假如我插入的元素够多,个人循环不够多,(我想过用递归实现,可是由于涉及二维数组的横向判断,因此我以为递归也不行),而后就是由于涉及到横向的判断,举个例子,假如A和B连了,B和C连了,B和D也连了,这个时候咱们就多了一路,由于二维数组移动的位置太不可控,因此位置的增长减小就存在很大的问题,因此就陷入了一直想用连续循环的这个弊病中,一时半会儿一直解决不了这个问题,就想着能不能用咱们pp15.1须要实现的方式,也就是用链表的方式。

  • 六、(1)首先咱们先构建这样的一个图:

(2)而后咱们须要构建相似链地址法绘制出一个以下图的图:


(3)个人新的一版思路是:当咱们在保存头结点的数组中找到开始的结点,而后再须要写循环进行对因而否链接进行判断,在进行将权重相加,可是我依旧又是毙了这一版,由于在偶尔的一天晚上凌晨,翻到了算法导论图论的这一部分,看到了里面讲解的有一部分叫作单源最短路径,发现这一部分和这个题目存在着很大的关联,就仔细的看了看,有一个算法就是针对此类题型设计的,叫作Dijkstra算法,我很感谢我当时买了这本书,让我从痛苦中走了出来。
(4)Dijkstra算法:

  • 一、这个算法被誉为贪婪算法最好的例子。贪婪算法通常分阶段求解一个问题,在每一个阶段他都把出现的当作是最好的例子。贪婪算法主要的问题在于,该算法不是总可以成功的。
  • 二、举个例子:

  • (1)第一个选择的顶点是v1,路径长是为0;该顶点标记为known。既然v1是known的,那么某些表项就须要调整。邻接到v1的顶点是v2和v4。这两个项获得调整。

  • (2)下一步,选取v4而且标记为known。顶点v3,v5,v6,v7是邻接的顶点,而它们实际上都须要调整。如图

  • (3)接下来选择v2,v4是邻接的点,但已是known的了,所以对它没有工做要作。v5是邻接的点但不作调整,由于通过v2的值2+10=12而长为3的路径已是已知的。图

  • (4)下一个被选择的顶点是v5,其值为3。v7是惟一的邻接顶点,可是它不用调整,由于3+6>5.而后选取v5,对v6的距离下调到3+5=8。如图:

  • (5)再下一个选取的顶点是v7,v6下调到5+1=6,如图:

  • (6)最后,咱们选取的顶点是v6。最后的表在下图中显示,在以下的图形显示算法期间是如何标记为known的以及顶点是如何更新的。

上周考试错题总结

本周无测试。

结对及互评

  • 本周结对学习状况
  • 博客中值得学习的或问题:
    • 内容详略得当;
    • 代码调试环节比较详细;
  • 基于评分标准,我给本博客打分:5分。得分状况以下:
  1. 正确使用Markdown语法(加1分):
  2. 模板中的要素齐全(加1分)
  3. 教材学习中的问题和解决过程, 一个问题加1分
  4. 代码调试中的问题和解决过程, 一个问题加1分

  • 博客中值得学习的或问题:
    • 内容详略得当;
    • 代码调试环节比较详细;
  • 基于评分标准,我给本博客打分:9分。得分状况以下:
  1. 正确使用Markdown语法(加1分):
  2. 模板中的要素齐全(加1分)
  3. 教材学习中的问题和解决过程, 一个问题加1分
  4. 代码调试中的问题和解决过程, 一个问题加1分

感悟

第一次要好好写写感悟了:

  • 一、我以为如今班里写博客呈现出一种我以为学习java或者学习编程很大的一个弊病,不只仅是咱们学生本身自己,还包括。。。你懂的。我以为咱们学习一门汇编语言应勤于练习,原理是须要了解,可是博客写的如此之多,难道就为了换个加分??是这样么?如今不少人写博客20小时,敲代码10分钟,难道如今不常见么,码云上,看看,抄抄,多快,不少人本身连脑子都不会动一下,因此我但愿不要把有心人的努力慢慢磨的没有了,我以为我如今为了写一篇博客花了太多的时间去完善个人博客,没有问题,没有教材,我以为那个只不过是由于不少人已经对于这样的形式趋于疲乏。咱们你们的时间都很重要,教材总结,咱们看了一遍,还得把教材的本身总结一下,我以为那不如让咱们别敲代码的了,就写博客,分不也很高。
  • 二、我本身自己对于分数并非很在乎,只不过只是本身期末的分数高低而已,学没学到真本事谁也不知道,我能够举个例子,个人结对小伙伴赵乾宸本是一个编码能力超强,脑子很是聪明的人,不少人真的不知道他有多强,可是如今这种形式,我以为博客从纪录分数变成如此的利益化,我以为自己意义就很弱了,不少人确定会给我说,那你写这么多干什么,由于我傻。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积)
目标 5000行 30篇 400小时
第一周 0/0 1/1 6/6
第二周 1313/1313 1/2 20/26
第三周 901/2214 1/3 20/46
第四周 3635/5849 2/4 20/66
第五周 1525/7374 1/5 20/86
第六周 1542/8869 2/5 25/111
第七周 1391/10260 1/6 20/131
第八周 4379/14639 2/8 25/156
第九周 3155/17794 1/9 30/186

参考资料

蓝墨云班课
Java程序设计
算法导论:别点了,是本书
数据结构与算法分析:别点了,是本书
Dijkstra 最短路径算法 秒懂详解

相关文章
相关标签/搜索