大家好我是苏麟 , 今天来聊聊图结构 .
我们平时在工作、学习中会大量使用图结构,不过呢在使用代码进行具体实现的时候极少使用图,主要是图里容易产生环,难以处理。
在算法里,考察图也不是很多,主要是图的表示非常复杂,初始化一个图就需要几十行代码,非常不利于面试。不过呢,在笔试、校招等场景还是可能考察图,所以为了提高自己的胜算,我们有必要掌握必要的图问题。
前面我们学了线性表和树,线性表局限于一个直接前驱和一个直接后继的关系,树也只能有一个直接前驱也就是父节点,当我们需要表示多对多的关系时,就用到了图。
图,是一种比树更为复杂的数据结构。树的节点之间是一对多的 关系,并且存在父与子的层级划分;而图的顶点(注意,这里不叫节点)之间是多对多的关系,并且所有顶点都是平等的,无所谓谁是父 谁是子。
在生活中,图这种数据结构的应用比比皆是。在交通当中,也常常涉及图的应用。
假设某个城市的地铁线路如下:
这些许许多多地铁站所组成的交通网络,也可被认为是数据结构当中的图。
为了方便处理,我们会将图抽象为只有顶点(vertex)和边的结构(edge),如下图所示
根据边是否有向,可以将图分为有向图和无向图。而根据顶点之间的边是否有权重,又分为带权图和不带权的图。
而不同顶点之间能够连通的线路就称为路径(Path),例如在上述中间有向图中C到D的路径为”C->B>D“,但是从D到C则没有路径,这称为两个结点不可达。
图结构常用来存储逻辑关系为“多对多”的数据。比如说,一个学生可以同时选择多门课程,而一门课程可以同时被多名学生选择,学生和课程之间的逻辑关系就是“多对多”。再举个例子, {V1,V2,V3,V4} 中各个元素之间具有的逻辑关系如下图所示 :
上图中,从V1可以找到V3、V4、V2,从 V3、V4、V2也可以找到 V1,因此元素之间具有“多对多”的逻辑关系,存储它们就需要用到图结构。
和链表不同,图中存储的各个元素被称为顶点(而不是节点)。拿上图来说,图中含有4个顶点,分别为顶点V1、V2、V3 和 V4。
通常情况下,我们习惯用 Vi 表示图中的顶点,且所有顶点构成的集合通常用 V 表示。比如说,上图中顶点的集合为 V={V1,V2,V3,V4}。
上图中各个顶点之间的关系都是双向的,这种情况下我们更习惯用下图来表示各个元素之间的关系 :
由 V1 可以找到 V2,同样由 V2 也可以找到 V1。类似上图这样,各个元素之间的联系都是双向的,这样的图结构称为无向图。如果元素之间存在单向的联系,那么这样的图结构称为有向图,例如:
从上面几个图,我们可以得到两个重要的结论 :
弧头和弧尾
有向图中,无箭头一端的顶点通常被称为"初始点"或"孤尾",箭头一端的顶点被称为"终端点"或"孤头"
入度和出度
对于有向图中的一个顶点 V 来说,箭头指向 V 的的数量为 V 的入度 (InDegree,记为 ID(V));箭头远离 V 的孤的数量为 V 的出度 (OutDegree,记为OD(V)) 。拿图中的顶点 V1来说,该顶点的入度为1,出度为 2,该顶点的度为 3.
(V1,V2) 和
无向图中描述两顶点 V1和 V2 之间的关系可以用(V1,V2) 来表示
有向图中描述从 V1 到 V2 的"单向"关系可以用
由于图存储结构中顶点之间的关系是用线来表示的,因此(V1,V2)还可以用来表示无向图中连接 V1 和 V2的线,又称为边:同样,
集合VR
图中习惯用 VR 表示图中所有顶点之间关系的集合。
例如,图中无向图的集合 VR={(v1,v2),(v1,v4),(v1,v3),(v3,v4)}
图中有向图的集合 VR={
路径和回路
无论是无向图还是有向图,从一个顶点到另一顶点途经的所有顶点组成的序列(包含这两个顶点),称为条路径。如果路径中第一个顶点和最后一个顶点相同,则此路径称为"回路”(或"环")。
在此基础上,若路径中各顶点都不重复,此路径被称为"简单路径",若回路中的顶点互不重复,此回路被称为"简单回路”(或简单环)。
拿图来说,从 V1 存在一条路径还可以回到 V1,此路径为{V1,V3,V4,V1},这是一个回路(环),而目还是一个简单回路 (简单环) .
在有向图中,每条路径或回路都是有方向的 .
权和网
有些场景中,可能会为图中的每条边赋予一个实数表示一定的含义,这种与边(或弧)相匹配的实数被称为"权",而带权的图通常称为网。例如:
子图
指的是由图中一部分顶点和边构成的图,称为原图的子图
连通图
前面讲过,图中从一个顶点到达另一顶点,若存在至少一条路径,则称这两个顶点是连通着的。例如图中,虽然V1 和 V3 没有直接关联,但从 V1 到 V3 存在两条路径,分别是 V1-V2-V3 和 V1-V4-V3,因此称 V1 和 V3 之间是连通的。
无向图中,如果任意两个顶点之间都能够连通,则称此无向图为连通图。例如,图中的无向图就是一个连通图,因为此图中任意两顶点之间都是连通的。
强连通图
有向图中,若任意两个顶点 Vi 和 Vj,满足从 V到 V 以及从 V到 Vi 都连通,也就是都含有至少一条通路,则称此有向图为强连通图。如图所示就是一个强连通图。
与此同时,若有向图本身不是强连通图,但其包含的最大连通子图具有强连通图的性质,则称该子图为强连通分量。
强连通分量如上图所示,整个有向图虽不是强连通图,但其含有两个强连通分量。
这期就到这里 , 下期见!