图及抽象数据类型ADTGraph的python实现

1.图(Graph)

graph:重在由一些基本元素构造而来的图,如点、线段等
图(Graph)是比树更为一般的结构,也是由边节点和边构成。实际上,树是一种具有特殊性质的图
图可以用来表示现实世界中很多事物,如道路交通系统、航班线路、互联网连接、大学中课程的先修次序

2.图中常用术语

  • 顶点Vertex(也称“节点Node”)
    是图的基本组成部分,顶点具有名称标识key,也可以携带数据项payload
  • 边Edge(也称“弧Arc”)
    作为2个顶点之间关系的表示,边连接两个顶点。边可以是无向或者有向的,相应的图称作“无向图”和“有向图”
  • 权重Weight
    为了表达从一个顶点到另一个顶点的“代价”,可以给边赋权;假如公交网络中两个站点之间的“距离”、“通行时间”和“票价”都可以作为权重。
    一个图G可以定义为G=(V,E)
    其中V是顶点的集合,E是边的集合,E中的每条边e=(v,w),v和w都是V中的顶点;如果是赋权图,则可以在e中添加权重分量
    下图为一个有向赋权图,权重为整数,有6个顶点及9条边
    在这里插入图片描述
    在这里插入图片描述
  • 路径Path
    图中的路径,是由边依次连接起来的顶点序列;无权路径的长度为边的数量;带权路径的长度为所有边权重的和。如下图的一条路径(v3,v4,v0,v1),路径长度为7+1+5=13
    在这里插入图片描述
  • 圈Cycle
    圈是首尾顶点相同的路径,如下图中(v5,v2,v3,v5)是一个圈。如果有向图中不存在任何圈,则称作“有向无圈图(directed acyclic graph:DAG)”
    在这里插入图片描述

3.抽象数据类型:ADT Graph

抽象数据类型ADT Graph定义如下:

  • Graph():创建一个空图
  • addVertex(vert):将顶点vert加入图中
  • addEdge(fromVert,toVert):添加有向边
  • addEdge(fromVert,toVert,weight):添加带权的有向边
  • getVertex(vKey):查找名称为vKey的顶点
  • getVertices():返回图中所有顶点列表
  • in:按照vert in graph的语句形式,返回顶点是否存在图中True/False

4.ADT Graph的实现方法

ADT Graph的实现方法有两种主要形式:
(1)邻接矩阵adjacency matrix
(2)邻接表adjacency list
两种方法各有优劣,需要在不同应用中加以选择

4.1 邻接矩阵adjacency matrix

矩阵的每行和每列都代表图中的顶点。如果两个顶点之间有边相连,设定行列值。无权边则将矩阵分量标注为1或者0;带权便则将权重保存为矩阵分量值。
在这里插入图片描述
邻接矩阵实现法的优点是简单,可以很容易得到定点是如何相连的。但如果图中的边数很少,则效率低下,成为“稀疏(sparse)”矩阵。而大多数问题所对应的图都是稀疏的,边远远少于V2这个量级。

4.2 邻接列表Adjacency List

邻接列表Adjacency List可以成为稀疏图的更高效实现方案。维护一个包含所有顶点的主列表(master list),主列表中的每个顶点再关联一个与自身有边连接的所有顶点的列表。
临界列表法的存储空间紧凑高效,很容易获得顶点所连接的所有顶点,以及连接边的信息。
在这里插入图片描述

5.图抽象数据类型的python实现

5.1 ADT Graph的实现:顶点Vertex类

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]

5.2 ADT Graph的实现:图Graph类

Graph保存了包含所有顶点的主表

#Graph类
class Graph:
    def __init__(self):
        self.vertList={}
        self.numVertices=0
    #新加顶点
    def addVertex(self,key):
        self.numVertices=self.numVertices+1#顶点数加1
        newVertex=Vertex(key)
        self.vertList[key]=newVertex
        return newVertex
    #通过key查找顶点
    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())
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值