总目录传送门:
目录
我们在算法题以及很多算法理论中,经常会讨论到DFS和BFS算法,也就是深度优先搜索算法(Depth-First-Search),和广度优先搜索算法(Breadth-First-Search)。算法一般都是基于某种具体的使用环境,或者说是某种数据结构之上的,那么DFS和BFS主要我们会使用在图和树这两种数据结构之上。
要讨论DFS和BFS,首先就要讨论图和树,这两个数据结构从大学的数据结构与算法到图论到后面的CG的学习都在使用。
图论中的图
图(Graph)
图的定义:
七桥问题:
大部分图论的开始解释图,都是引用了一个很经典的例子:哥德堡七桥问题。这个问题作为图论与几何拓扑学的开端,很好的把抽象具体化:
题目大概是这样的:
18世纪初普鲁士的哥尼斯堡,有一条河穿过,河上有两个小岛,有七座桥把两个岛与河岸联系起来(如概述图)。有个人提出一个问题:一个步行者怎样才能不重复、不遗漏地一次走完七座桥,最后回到出发点。
这道题数学家欧拉将其抽象成了一个图,并且的到了欧拉回路和欧拉定理:
图的数学定义:
具体解法很多地方有提到,就不过多赘述了。所以在数学领域的图,就是一个对应具体问题的抽象表达。在数学的解释里,图是一种网状数据结构,图是由非空定点集合和一个描述顶点关系的集合组成
定义如下:
Graph =(V,E)
V = {x|x∈某个数据对象}
E = {<u,v>|P(u,v)^(u,v∈V)}
V 是具有相同特性的数据元素的集合,V中的数据元素通常称为顶点(Vertex)
E 是两个顶点之间关系的集合,P(u,v)表示u和v之间有特定的关联属性
所以在数学中图是可以用公式表示出来的,这就是图的基本数学定义。
在基本图的理论基础上,加入了连线的方向,就进一步区分成了有向图和无向图:
有向图:
若<u,v>∈E,则<u,v>表示从顶点u到顶点v的一条弧,并称u为弧尾或起始点,v为弧头或终止点,此时图中的顶点是有方向的,这样的图称为有向图
无向图:
若<u,v>∈E,则必有<u,v>∈E,即关系E是对称的,此时可以使用一个无序对(u,v)来代替两个有序对,他表示顶点u和顶点v之间的一条边,此时图中顶点连线是没有方向的,这种图称为无向图
加权图:
在此基础上,我们在他的每条边上,加入权重(weight),就形成了权重图。在实际使用中,图不但要表示某种关系,而且图的边与实际数有关,即每条边都有其相关的实数,称为权,在不同问题中,权值可以代表距离,时间以及价格等不同的属性。也可以说是代表边对于其连接的两顶点关系的强度。
连通图:
任意两点之间都有路径连接的图叫做连通图。顶点连接的边数叫做这个顶点的度。
度:
像树中的度一样,每个顶点,有几条线将它连接,它的度TD(v)就是多少,有向图还分有入度ID(v)和出度OD(v)。比如上图的顶点d的度就是4,入度是2(d->b,d->a),出度是2(e->d,c->d)
路径(path):
在图上任取两顶点,分别作为起点(start vertex)和终点(end vertex),我们可以规划许多条由起点到终点的路线。不会来来回回绕圈子、不会重复经过同一个点和同一条边的路线,就是一条“路径”。两点之间存在路径,则称这2个顶点是连通的(connected)。
路径也有权重。路径经过的每一条边,沿路加权重,权重总和就是路径的权重(通常只加边的权重,而不考虑顶点的权重)。在路网中,路径的权重,可以想象成路径的总长度。在有向图中,路径还必须跟随边的方向。 值得注意的是,一条路径包含了顶点和边,因此路径本身也构成了图结构,只不过是一种特殊的图结构。
比如上图中的c->b->e就是一条路径。
环/回路:
环,也成为环路,是一个与路径相似的概念。在路径的终点添加一条指向起点的边,就构成一条环路。通俗点说就是绕圈。 环本身也是一种特殊的图结构。
比如上图中的b->e->d->b就是一个环。
简单来说:
图由顶点(vertex,node)和边(edge)组成。顶点就是代表对象,因为有时候题不会直接给顶点,而是某种对象,直接看成顶点即可。我们使用链接两顶点之间的线段来表示。顶点的集合V,边的集合是E,所以图记为G = (V,E), 连接两点u和v的边用e=(u,v)表示。
图上的搜索算法,就是从图中的一个顶点出发,到另一个顶点的路径。图有两种存储方法,邻接矩阵和邻接表。
图的储存:
邻接矩阵:
邻接矩阵使用二维数组来表示图。gi表示的是顶点i和顶点j的关系。
由于在无向图中,只需要知道顶点i和j之间是否有边相连即可,因此如果顶点i和顶点j之间有边相连,那么g [i] [j] 和 g [j] [i]就设为1,否则设为0。这样就可以表示一个无向图了(也叫双向图)。
由于在有向图中,只需要知道是否有从顶点i发出指向顶点j的边,因此如果顶点i有一条指向j的边,那么g[i] [j]就设为1,否则就设为0(注意这是有向图)。
在带权图中,gi表示的是顶点i到顶点j的边的权值。由于在边不存在的情况下,如果将gi设为0,就无法和权值为0的情况区分开来,因此选取适当的较大的常数inf,然后令gi=inf。
使用邻接矩阵的好处是可以在常数时间内判断两点之间是否有边存在,但是很消耗空间,如果点数>1000就很麻烦了。
大部分情况下,只需要保存权值最小(最大)的边就可以了,所以在这种情况下可以无视其他的边。必须保存所有的边时可以使用邻接表。
邻接表:
邻接表是通过把从顶点i出发有到顶点j的边,这样的信息保存在链表中来表示图的。
以上就是一些图的基本概念,很多数据来自参考:图和树的基本概念与认识_CS33sun的博客-CSDN博客_图和树
以及百度百科,如有疑问欢迎讨论