1 基本概念
无向图:即图的边没有方向,边一般用弧形括号表示()
有向图:图的边有方向,边一般用尖括号表示<>
完全图:图的每两个顶点之间有边链接
连通图:图的每两个顶点之间有路径链接
无向完全图:无向图中,任意两个顶点之间都存在边。
有向完全图:有向图中,任意两个顶点之间都存在方向互为相反的两条弧。
2 图的存储
2.1 邻接矩阵
用两个数组,一个数组保存顶点集,一个数组保存边集。
2.2 邻接表
对于带权值的网图,可以在边表结点定义中再增加一个weight的数据域,存储权值信息即可。
3 图的遍历
"""
@Author:Lixiang
"""
#定义一个图的结构
graph={
'A':['B','C'],
'B':['A','C','D'],
'C':['A','B','D','E'],
'D':['B','C','E','F'],
'E':['C','D'],
'F':['D']
}
3.1 深搜-stack实现
"""
@Author:Lixiang
"""
#DFS指的是深度优先搜索 回溯法(会回看前面的节点)
#一直往前走,走不下去往回跳
#使用stack来进行深度的顺序
#把栈顶元素去除,在把临接点放入
#其实并不难,只要把队列改成栈就可以了
def DFS(graph,s):#图 s指的是开始结点
#需要一个队列
stack=[]
stack.append(s)
seen=set()#看是否访问过
seen.add(s)
while (len(stack)>0):
#拿出邻接点
vertex=stack.pop()#这里pop参数没有0了,最后一个元素
nodes=graph[vertex]
for w in nodes:
if w not in seen:#如何判断是否访问过,使用一个数组
stack.append(w)
seen.add(w)
print(vertex)
3.2 广搜-queue实现
"""
@Author:Lixiang
"""
#BFS 广度优先搜索 层序遍历
def BFS(graph,s):#graph图 s指的是开始结点
#需要一个队列
queue=[]
queue.append(s)
seen=set()#看是否访问过该结点
seen.add(s)
while (len(queue)>0):
vertex=queue.pop(0)#保存第一结点,并弹出,方便把他下面的子节点接入
nodes=graph[vertex]#子节点的数组
for w in nodes:
if w not in seen:#判断是否访问过,使用一个数组
queue.append(w)
seen.add(w)
print(vertex)
4 拓扑排序
如果我们有如下的一个有向无环图,我们需要对这个图的顶点进行拓扑排序,过程如下:
首先,我们发现V6和v1是没有前驱的,所以我们就随机选去一个输出,我们先输出V6,删除和V6有关的边,得到如下图结果:
然后,我们继续寻找没有前驱的顶点,发现V1没有前驱,所以输出V1,删除和V1有关的边,得到下图的结果:
然后,我们又发现V4和V3都是没有前驱的,那么我们就随机选取一个顶点输出(具体看你实现的算法和图存储结构),我们输出V4,得到如下图结果:
然后,我们输出没有前驱的顶点V3,得到如下结果:
然后,我们分别输出V5和V2,最后全部顶点输出完成,该图的一个拓扑序列为:
v6–>v1—->v4—>v3—>v5—>v2
5 图的最小生成树
树是一种没有回路和环路的图
5.1 普利姆算法
步骤
步骤1:在所有的边中选择一个边权最小的边(如果具有相同最小权值的边有好几个,那么就随便选一个),使用这个边将两个节点连接起来,也就是将这个边加入生成树结构中
步骤2:将上述步骤中用到的点,存放在一个数组中,这个集合称之为“用过的点的集合”(一会儿我们要用这个集合来判断新选择的边是不是会构成回路)
步骤3:查找和所有已经用过的点相关的边,在这些边中挑出一个权值最小的边,加入生成树结构中,
但是在挑选的过程中我们需要保证:被选择的点,不能够出现在“用过的点的集合”中,因为如果出现这种情况,说明选择的边将使得图中出现回路,那就不是树结构了
步骤4:将这个距离最近的点,同样加入“用过的点的集合”
步骤5:重复步骤3-4,直到边的个数为节点的数量减一时候,说明所有的节点都已经加入最小生成树结构中了,程序终止
5.2 克鲁斯克尔(Kruskal)算法
记Graph中有v个顶点,e条边;
新建图Graphnew,Graphnew中拥有原图中的v个顶点,但没有边;
将原图Graph中所有e条边按权值从小到大排序;
循环:从权值最小的边开始,判断并添加每条边,直至添加了
n-1条边
:
图中的路径按照权值的大小的排序为
AF 1;
BE 4;
BD 5;
BC 6;
DC:10;
BF 11;
DF 14;
AE 16;
AB 17;
EF 33;
算法的处理过程如下
DC形成环路了,舍去。