数据结构 | 图和图算法

作者: 水土七口刀 | 来源:发表于2020-03-20 06:34 被阅读0次

三要素

  • 顶点:顶点(也称“节点 node”)是图的基础部分。
  • 边:边(也称“弧 arc”)是图的另一个基础组成部分。如果一条边连接两个顶点,则表示两者具有联系。边可以是单向的,也可以是双向的。
  • 权重:为了表达从一个顶点到另一个顶点的“代价”,可以给边赋权。

二概念

  • 路径:图中的路径,是由边依次连接起来的顶点序列。
  • 环:有向图里的环是首尾顶点相同的路径。没有环的图称为“无圈图acyclic graph”,没有环的有向图称为“有向无环图 directed acyclic graph 或 DAG”。

图 抽象数据类型(Abstract Data Type,ADT)相关定义

  • Graph():创建一个空的图
  • addVertex(vert):将一个顶点 Vertex 对象加入图中
  • addEdge(fromVert, toVert):添加一条有向边
  • addEdge(fromVert, toVert, weight):添加一条带权的有向边
  • getVertex(vertKey):查找图中名称为 vertKey 的顶点
  • getVertices():返回图中所有顶点列表

图的两种实现方法

  • 邻接表


    图的邻接表表示
  • 邻接矩阵


    图的邻接矩阵表示

图的python实现

  • 在 Python 中使用字典将使得邻接表的实现变得很容易。在我们实现图表抽象数据类型时,我们可以创建两个类Graph 和 Vertex。Graph 保存了包含所有顶点的主表,Vertex则描绘了图表中顶点的信息。
#Vertex
class Vertex:
  def __init__(self,key):
    self.id = key
    self.connectedTo = {}
  def addNeighbor(self,nbr,weight=0):
    self.connectedTo[nbr] = weight
  def __str__(self):
    return str(self.id) + ' connectedTo: ' + str([x.id for x in self.connectedTo])
  def getConnections(self):
    return self.connectedTo.keys()
  def getId(self):
    return self.id
  def getWeight(self,nbr):
    return self.connectedTo[nbr]
#graph
class Graph:
  def __init__(self):
    self.vertList = {}
    self.numVertices = 0
  def addVertex(self,key):
    self.numVertices = self.numVertices + 1
    newVertex = Vertex(key)
    self.vertList[key] = newVertex
    return newVertex
  def getVertex(self,n):
    if n in self.vertList:
      return self.vertList[n]
    else:
      return None
  def __contains__(self,n):
    return n in self.vertList
  def addEdge(self,f,t,cost=0):
    if f not in self.vertList:
      nv = self.addVertex(f)
    if t not in self.vertList:
      nv = self.addVertex(t)
      self.vertList[f].addNeighbor(self.vertList[t], cost)  
  def getVertices(self):
    return self.vertList.keys()
  def __iter__(self):
    return iter(self.vertList.values())

广度优先搜索(BFS)算法

已知一个图 G 和它的一个起始顶点 s,广度优先搜索(BFS)通过搜索图中的边来找到图 G 中所有和 s 有路径相连的顶点。
其显著的特点是在搜索达到距离 k+1 的顶点之前,BFS 会找到全部距离为 k 的顶点。有一个很好的方法去想象广度优先搜索(BFS)的运行原理,那就是建造一棵以 s 为根的树的过程,一次建造树的一层,同时,广度优先搜索(BFS)在增加层次前,会保证将始顶点所有的子顶点都添加在了树中。
为了进一步追踪这一过程,这里的 BFS 算法在搜索过程中,会给每一个顶点染色为白色、灰色或黑色。每一个顶点在被构建时都被初始化为白色,在这之后,白色代表的是尚未被发现的顶点。当一个顶点被第一次发现后,它被染成灰色,当广度优先搜索(BFS)完全探索完一个顶点后,它被染成黑色。
这意味着一旦一个节点染成了黑色,它就没有邻近的白色节点;而另一方面,如果一个顶点被标识为了灰色,这就意味着其附近可能还存在着未探索的顶点等待被探索。

深度优先搜索(DFS)算法。

BFS(广度优先搜索算法)是一次建立搜索树的一层,而 DFS 算法则是尽可能深的搜索树的一枝。

拓扑排序

  • 拓扑排序可以将一个有向无环图(DAG)转换为一个只含它所有顶点的线性排列,例如如果一个图G包含一个边界(v,w),然后我们就可以按顺序将顶点 v 放在顶点 w 之前。
  • 拓扑排序是深度优先搜索(DFS)的一个简单却有效的应用。拓扑排序的算法遵从以下法则:
    1. 为所求图问题调用 DFS 函数,调用 DFS 的主要原因是为了计算每一个事件顶点的完成时间。
    2. 按完成时间降序将事件顶点存储在一个列表中。
    3. 将列表作为拓扑排序的结果返回。


相关文章

网友评论

    本文标题:数据结构 | 图和图算法

    本文链接:https://www.haomeiwen.com/subject/kfsxyhtx.html