知识点
引入
图的定义和相关术语
图的实现
广度优先搜索
深度优先搜索
最短路径问题:
还有其他前往金门大桥的路线,但它们更远(需要四步)。这个算法发现,前往金门大桥的最短路径需要三步。
这种问题被称为最短路径问题(shortest-path problem)。
生活中经常要找出最短路径,这可能是前往朋友家的最短路径,也可能是国际象棋中把对方将死的最少步数。
解决最短路径问题的算法被称为广度优先(breadth-first search,BFS)搜索。
图的定义
标准定义:在数学中,图是描述于一组对象的结构,其中某些对象对在某种意义上是“相关的”。这些对象对应于称为顶点的数学抽象(也称为节点或点),并且每个相关的顶点对都称为边(也称为链接或线)。通常,图形以图解形式描绘为顶点的一组点或环,并通过边的线或曲线连接。
二元组的定义: 图G是一个有序二元组(V,E),其中V称为顶集(Vertices Set),E称为边集(Edges set),E与V不相交。它们亦可写成V(G)和E(G)。其中,顶集的元素被称为顶点(Vertex),边集的元素被称为边(edge)。E的元素都是二元组,用(x,y)表示,其中x,y∈V。
三元组的定义: 图G是指一个三元组(V,E,I),其中V称为顶集,E称为边集,E与V不相交;I称为关联函数,I将E中的每一个元素映射到V。如果e被映射到(u,v),那么称边e连接顶点u,v,而u,v则称作e的端点,u,v此时关于e相邻。同时,若两条边i,j有一个公共顶点u,则称i,j关于u相邻。
图:Graph=(V,E)
V:顶点(数据元素)的有穷非空集合;
E:边的有穷集合。
无向图:每条边都是无方向的
有向图:每条边都是有方向的
一个是无向图一个是有向图
完全图:任意两个点都有一条边相连
n(n-1)/2 条边 n(n-1) 条边
稀疏图:有很少边或弧的图。
稠密图:有较多边或弧的图。
权和网:图中边或弧所具有的相关数称为权。带权的图称为网。
邻接:有边/弧相连的两个顶点之间的关系。存在(vi, vj),则称vi和vj互为邻接点;
存在<vi, vj>,则称vi邻接到vj,vj邻接于vi
关联(依附):边/弧与顶点之间的关系。
存在(vi, vj)/ <vi, vj>,则称该边/弧关联于vi和vj
顶点的度:与该顶点相关联的边的数目,记为TD(v)
在有向图中, 顶点的度等于该顶点的入度与出度之和。
顶点v 的入度:是以v 为终点的有向边的条数, 记作ID(v)
顶点v 的出度:是以v 为始点的有向边的条数, 记作OD(v)
当有向图中仅1个顶点的入度为0,其余顶点的入度均为1,此时是何形状?
是树!而且是一棵有向树!
路径:接续的边构成的顶点序列。
路径长度:路径上边或弧的数目/权值之和。(有两种可能,弧或者边)
回路(环):第一个顶点和最后一个顶点相同的路径。
简单路径:除路径起点和终点可以相同外,其余顶点均不相同的路径。
简单回路(简单环):除路径起点和终点相同外,其余顶点均不相同的路径。
连通图(强连通图):在无(有)向图G=( V, {E} )中,若对任何两个顶点v、u 都存在从v 到u 的路径,则称G是连通图(强连通图)。
子图:
设有两个图G=(V,{E})、G1=(V1,{E1}),若V1εV,E1 εE,则称G1是G的子图。例:(b)、(c) 是(a) 的子图:
连通分量(强连通分量)
无向图G 的极大连通子图称为G的连通分量。
极大连通子图意思是:该子图是G 连通子图,将G 的任何不在该子图中的顶点加入,子图不再连通。
图的遍历
1遍历定义:从已给的连通图中某一顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历,它是图的基本运算。
2遍历实质:找每个顶点的邻接点的过程
3图的特点:图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。
图常用的遍历:
深度优先搜索
广度优先搜索
广度优先搜索
广度优先Breadth-First-Search(BFS)搜索是一种用于图的查找算法,可帮助回答两类问题。
第一类问题:从节点A出发,有前往节点B的路径吗?(能否连通)
第二类问题:从节点A出发,前往节点B的哪条路径最短?(最短路径问题)
前面计算从双子峰前往金门大桥的最短路径,这个问题属于第二类问题:哪条路径最短。
第一类问题:先找自己连通的,再找自己连通的连通的
回答第二类问题:朋友是一度关系,朋友的朋友是二度关系。一度关系胜过二度关系,二度关系胜过三度关系,以此类推。
广度优先搜索先在一度关系中查找,再在二度关系中查找。
因此找到的是关系最近的芒果销售商。广度优先搜索不仅查找从A到B的路径,而且找到的是最短的路径。
注意,只有按添加顺序查找时,才能实现这样的目的。
有一个可实现这种按添加顺序检查的数据结构,那就是队列(queue)。
用队列实现:广度优先搜索找卖菠萝的朋友(一个入队一个出队)
队列是一种先进先出(First In First Out,FIFO)的数据结构,而栈是一种后进先出(Last In First Out,LIFO)的数据结构。
知道队列的工作原理,就可以实现广度优先搜索
具体代码实现
Peggy既是Alice的朋友又是Bob的朋友,因此她将被加入队列两次:一次是在添加Alice的朋友时,另一次是在添加Bob的朋友时。因此,搜索队列将包含两个Peggy。
但你只需检查Peggy一次,看她是不是芒果销售商。如果你检查两次,就做了无用功。
因此,检查完一个人后,应将其标记为已检查,且不再检查他。
否则就可能会导致无限循环。
检查一个人之前,要确认之前没检查过他。
可使用一个列表来记录检查过的人。
广度优先搜索的时间
运行时间
若在整个人际关系网中搜索芒果销售商,就意味着你将沿每条边前行,因此运行时间至少为O(边数)。
你还使用了一个队列,其中包含要检查的每个人。将一个人添加到队列需要的时间是固定的,即为O(1),因此对每个人都这样做需要的总时间为O(人数)。
所以,广度优先搜索的运行时间为O(人数+ 边数),这通常写作O(V + E),其中V为顶点(vertice)数,E为边数。
广度优先搜索的基本思想文章来源:https://www.toymoban.com/news/detail-523236.html
基本思想:——仿树的层次遍历过程文章来源地址https://www.toymoban.com/news/detail-523236.html
到了这里,关于数据结构图论的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!