数据结构 图的基本概念和算法

数据结构 图的基本概念和算法

彩笔离散数学学的很烂,刚好数据结构学到了,这边顺便梳理一下。

工具:draw.io(开启数学排版,输入latex公式时不能换行),visual studio 2022.

1. 点

结点(顶点)

邻接点:假若顶点v 和顶点w 之间存在一条边, 则称顶点v 和w 互为邻接点。

终点(Destination):路径的最后一个顶点。

源点(Source):一般指带权有向无环图中入度为0的点。

汇点:一般指带权有向无环图中出度为0的点。

2. 边

边:一般指无向的边。

弧:指有向的边,弧头(箭头),弧尾(箭头尾部)。

w_{k,i}是<v_{k},v_{i}>的弧值,其中v_{i}是弧头,v_{k}是弧尾。

弦:无向图中,连接一个环非相邻两个顶点的边。

平行边:两点间有多条同始同终的边。

重数:平行边的条数。

出度:从某点出的边数。

入度:从某点入的边数。

节点度:和该节点相关联的边的条数,又称关联度。

1.无向图中所有顶点的度之和等于边数的2倍。

2.有向图中所有顶点的入度之和等于所有顶点的出度之和。

3. 次数为奇数的结点(奇点)必为偶数个。

点的度数(次数):该点的入度+出度。

回路(环):第一个顶点和最后一个顶点相同的路径。

路径:由顶点和相邻顶点序偶构成的边所形成的序列。

简单路径:路径上的各顶点均不重复。

简单回路:起点终点重合,其余经过的顶点不重复出现的回路叫简单回路。

基本路径:不包含任何重复边和重复顶点的路径。

基本回路:起点终点重合,其余经过的点和边没有重复的回路。

可达:点1到点2存在一条路径,则1到2可达。

3. 图

G=<V,E>。G表示个图,V是图G中顶点的集合,E是图G中边的集合。

有向图:每条边都有方向

无向图:每条边都无方向

多重图:有平行边。

线图:无平行边。

简单图:既不含平行边也不含自环的图。

平凡图:仅一个结点。

稠密图:接近完全图。

稀疏图:边数很少的图。

无向完全图:每对顶点之间都恰连有一条边的无向图。

有向完全图:各边都有方向,且每两个顶点之间都有两条方向相反的边连接的图。

连通:无向图中,任意两点都有路径相连。有向图中,任意两点都有路径相连,且路径的每一条边同向。

连通图:任意两点连通(没有孤立点)(相互可达)。

连通分图:子图A连通,没有比A更大的子图是连通的->图A是原图的连通分图。

连通分量:无向图G的极大连通子图称为G的连通分量。

点连通度:为使图G不连通或成为平凡图,至少需要从G中删除的顶点数量称作G的点连通度,k。

边连通度:为使图G不连通或成为平凡图,至少需要从G中删除的边的数量称作G的边连通度,l。

最小度:无向图G中度数最小顶点的度数,d。k<=l<=d

单向连通图:有向图D中任意两点vi,vj,都有一条vi到vj的路径或者vj到vi的路径(单向可达)。

弱连通图:有向图D的底图是无向连通图。

强连通图:有向图D任意两个结点彼此可达。

网图或网:边(或弧)上标识有权的图。自己和自己为0,非邻接顶点为∞,权为权值。

子图:节点集和边集分别是某一图的节点集的子集和边集的子集的图。

生成子图:设G=<V,E>,G1=<V1,E1>.当V1=V,E1

www.zeeklog.com  - 数据结构 图的基本概念和算法

E时,G1是G的生成子图。

导出子图:设

www.zeeklog.com  - 数据结构 图的基本概念和算法

以V2作为结点集,以两个端点都在V2中的边的全体为边集的G的子图,称为V2导出的G的子图,简称V2的导出子图。

或者说点集合V2是原图点集合V的非空子集,然后再在原图的边集合E中找到两个端点均在点集合V2中的边元素,并将这些边元素称成一个新的边集合E2,得到的这个边集合就是导出子图的边集合。

补图:设G=<V,E>为简单图,G2=<V,E1>为完全图,则称G1=<V,E1-E>为G的补图,记为

www.zeeklog.com  - 数据结构 图的基本概念和算法

补图就是从完全图中删除图G中的边。

4. 树相关

生成树:设G为无向连通图,T是G的生成子图且为树,则T是G的生成树。若G中顶点数为n,则T含有n-1条边。G在T中的边称为树枝,不在的边称为弦。

有向树:是只有一个顶点的入度为0,其余顶点的入度均为1的有向图。

生成森林:在非连通图中,多个连通分量对应的多棵生成树就构成了整个非连通图的生成森林。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法
生成森林

余树:一个连通无向图的生成树中被删去任一条边后形成的树。

最小生成树:带权图中权值最小的生成树。

5. 图的存储

邻接矩阵:对于有向图vij表示顶点i到j是否有弧(有1无0),当弧带权重时,vij表示顶点i到j弧的权重(没有弧则∞)。对于无向图vij表示顶点i到j是否有边(有1无0),当边带权重时,vij表示顶点i到j边的权重(没有边则∞)。

正邻接表:最左侧格子为起始点。在有向图中,为图中每个顶点vi建立一个出边表。

逆邻接表:最左侧格子为终点。在有向图中,为图中每个顶点vi建立一个入边表。

顶点表:左侧为编号,右侧为结点名。

边表:前两列为构成边的节点,第三列为该边的权重。

1. 设一有向图G=(V,E),其中V={a,b,c,d,e} , E={<a,b>, <a,d>, <b,a>, <c,b>, <c,d>, <d,e>,<e,a>, <e,b>, <e,c>},画正邻接表,逆邻接表。

www.zeeklog.com  - 数据结构 图的基本概念和算法
正邻接表
www.zeeklog.com  - 数据结构 图的基本概念和算法
逆邻接表

2. 参照下面带权无向图,画邻接矩阵,顶点表,边表。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法
邻接矩阵表示
www.zeeklog.com  - 数据结构 图的基本概念和算法

6. 图相关算法

1. DFS与BFS

www.zeeklog.com  - 数据结构 图的基本概念和算法
有向图
www.zeeklog.com  - 数据结构 图的基本概念和算法
邻接矩阵表示

深度优先搜索(DFS)(Depth First Search):从图中一个未访问的顶点 V 开始,沿着一条路一直走到底,然后从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底...,不断递归重复此过程,直到所有的顶点都遍历完成。

如上图,先取v1,然后遍历v1邻接点v2,v2所有邻接点都被访问,回退查找v1未被访问的邻接点v4,然后遍历v4邻接点v3,遍历v3邻接点v5。

上述深度优先遍历序列:v1 v2 v4 v3 v5。

广度优先搜索(BFS)(Breadth First Search):先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问到;由近到远访问,依次访问和v有路径长度为1、2、3..的顶点。图中尚有顶点未访问到,则另选图中一个未曾被访问的顶点做起点,重复上述过程,直至所有顶点被访问完为止。

如上图:先取v1,然后取v1邻接点v2,v4,然后取v4邻接点v3,然后取v3邻接点v5。

上述广度优先遍历序列:V1 V2 V4 V3 V5。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法

2. Prim与Kruskal 求最小生成树

普利姆算法(prim):设图G=<V,E>,从V中取一点放入V1集合中,查找一个起始点在V1集合中,终点在(V-V1)集合中的最小权值的边,将终点放入V1集合中,重复上述操作,直到V1包含G所有顶点。

如图6-27,若从顶点2出发,此时2在V1中且边(2,4)权值最小,取顶点4,此时4在V1中且边(4,3)权值最小,取顶点3,然后以此类推取顶点1,6,5。

克鲁斯卡尔算法(Kruskal):设图G=<V,E>,依次从E中取权值最小的边(或弧)并不构成回路,直到构成加权连通图的最小生成树。(适用于稀疏图)

如图6-27,先取此时权值最小的边(4,3),然后依次取(4,1),(5,6),(3,6),(4,2)。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法
prim算法过程
www.zeeklog.com  - 数据结构 图的基本概念和算法
kruskal算法过程

3. Dijkstra

迪杰斯特拉算法(dijkstra):图中某一个顶点,到其它顶点之间的最短路径.时间复杂度为O(n^2)。   1. 假设S为最短路径已确定的顶点集,V-S是最短路径尚未确定的顶点集。D[v]为u到v的最短路径长度,初始时,将源点u放入S中    2. 初始D[v],v∈ V-S,D[v]=w<u,v>    3. 选取点k使D[k]=min{D[v]: v∈ V-S}    4. 将k添入S    5.  若V-S不空,重新计算D[v]值,其中v∈ V-S    6. If (D[v]> D[k]+w<k,v>){D[v]= D[k]+w<k,v>;    并修改源点到v的路径上的点为源点到k的路径加上点v}    7. 若V-S为空,则结束,否则重复步骤第三     如下图,以v4为源点,写出迪杰斯特拉算法过程。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法
//伪代码分析过程
设G=<V,E,W>,源点v4
V={v1, v2, v3, v4, v5, v6}

S={v4}
    dist[4]=0
    dist[2]=20, dist[6]=15,
    dist[1]=dist[3]=dist[5]=∞

S={v4,v6}
    dist[4]=0,dist[6]=15,
    dist[2]=20,
    dist[1]=dist[3]=dist[5]=∞

S={v4,v6,v2}
    dist[4]=0,dist[6]=15,dist[2]=20,
    dist[1]=30,dist[5]=50,//v2与v5,v2与v1相邻,需重新计算v4到v5,v1的路径长度
    dist[3]=∞

S={v4,v6,v2,v1}
    dist[4]=0,dist[6]=15,dist[2]=20,dist[1]=30,
    dist[3]=45,dist[5]=50//v1与v3相邻,重新计算了v4到v3的路径长度

S={v4,v6,v2,v1,v3}
    dist[4]=0,dist[6]=15,dist[2]=20,dist[1]=30,dist[3]=45,
    dist[5]=50

S={v4,v6,v2,v1,v3,v5}
    dist[4]=0,dist[6]=15,dist[2]=20,dist[1]=30,dist[3]=45,dist[5]=50  
www.zeeklog.com  - 数据结构 图的基本概念和算法

4. Floyd

弗洛伊德算法(Floyd):图中每一个顶点,到其它顶点之间的最短路径.时间复杂度为O(n^3)。

要求的解是一个矩阵S[N][N],其中S[i][j]表示结点i到j的最短路径

Floyd算法过程描述如下:  1、 首先S以边集M初始化,得到所有的直接连通代价;   2、 依次考虑第k 个结点,对于S中的每一个S [ i ][j],判断是否满足:   S[ i ][j]>S[ i ][k]+S[k][j] ,如果满足则用 S[ i ][k]+S[k][j] 代替S [ i ][j] ,此为第 k步;   3、 k循环取遍所有结点,算法结束时,S为最终解。

求下图每个顶点到其他顶点的最短路径。

www.zeeklog.com  - 数据结构 图的基本概念和算法
www.zeeklog.com  - 数据结构 图的基本概念和算法
初始化
www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点a

上图加入中间顶点a后,路径多了e->a->b和e->a->c。

www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点b
www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点c

ace替换abe

www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点d
www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点e
www.zeeklog.com  - 数据结构 图的基本概念和算法
加入中间顶点f,算法结束

bfea替换 bea ,bfeac替换beac,bfeacd替换beacd。

5. AOV-网与拓扑排序

有向无环图(Directed Acycline Graph):简称DAG图。

AOV-网(Activity On Vertex Network):顶点表示活动的图。有向图顶点表示活动,弧表示活动间的优先关系。

拓扑排序:将AOV-网中所有顶点排成一个线性序列,该序列满足:若在AOV-网中由顶点vi到vj有一条路径,则再该线性序列中的顶点vi必定再vj之前。

拓扑排序的过程
(1)在有向图中选一个无前驱的顶点且输出它。
(2)从图中删除该顶点和所有以它为尾的弧。
(3)重复(1)和(2),直至不存在无前驱的顶点。
(4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在环,否则输出的顶点序列即为一个拓扑序列。

www.zeeklog.com  - 数据结构 图的基本概念和算法

6. AOE-网与关键路径

AOE-网(Activity On Edge):以边表示活动的网。带权有向无环图中,顶点表示事件,弧表示活动,权表示活动持续的时间。

由于整个工程只有一个开始点和一个完成点,故在正常的情况(无环有向带权图)下,网中只有一个入度为零的点,称作源点,也只有一个出度为零的点,称作汇点。

带权路径长度:在AOE网中,一条路径各弧上的权值之和称为该路径的带权路径长度(后面简称路径长度)。

关键路径(Critical Path):要估算整项工程完成的最短时间,就是要找一条从源点到汇点的带权路径长度最长的路径。

关键活动:关键路径上的活动叫做关键活动(时间余量为0)。

某些(注意不是任一)关键活动提前完成,整个工程将会提前完成。(有点类似木桶效应吧)

Ve(i):事件vi最早发生时间。Ve(i)是从源点到Vi的最长路径长度。

Vl(i):事件vi最晚发生时间。

e:活动最早开始时间。弧尾顶点最早开始时间。

l:活动最晚开始时间。弧头顶点最迟时间-权值。

时间余量(期限余量):l(i)-e(i),在此范围内的适度延误不会影响整个工程的工期。

求解下图关键路径和关键活动。

www.zeeklog.com  - 数据结构 图的基本概念和算法

拓扑排序:V0V1V2V3V4V5V6V7V8V9

逆拓扑排序:V9V8V7V6V5V4V3V2V1V0

www.zeeklog.com  - 数据结构 图的基本概念和算法

综上,关键路径为:(V0,V2,V3,V6,V8,V9),关键活动为:(a2,a4,a8,a12,a14)。

解题过程详解:

  1. 写出拓扑排序和逆拓扑排序。
  2. 画表格,根据拓扑排序的顺序写Ve行,V0到V0距离为0,V0到V1距离为5,...,V1和V2到V3有弧,Ve(V3)=Max{Ve(V1)+3,Ve(V2)+12}=Max{8,18}=8,...。
  3. 最后的V9先照着上面的30写下来,根据逆拓扑排序的顺序写Vl行,V8可以到V9,路径为2,故vl(V8)=30-2=28,...,V4可以到V6和V7,vl(V4)=Min{Vl(V6)-1,Vl(V7)-4}=22,...。
  4. 然后求e,a1弧尾V0最早开始时间0,a2弧尾V0最早开始时间0,...,a14弧尾V8最早开始时间28。
  5. 然后求l,a1弧头V1最晚开始时间15,减去a1权值5后为10,...,l(a14)=30-2=28。
  6. 最后算时间余量,写关键路径和关键活动。

上面内容有问题麻烦指正!

业精于勤荒于嬉,行成于思毁于随。--韩愈

7. 一些性质

1. 对于一个具有n个顶点的有向图的边数最多有n*(n-1)。

部分参考资料

《数据结构》严蔚敏 李冬梅 吴伟民

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk