1.“图”这部分分为无向图 、有向图、无向网(带权图)、有向网(带权图)四个内容。

图的顺序存储:邻接矩阵的存储形式

图的链式存储与顺序存储的组合:邻接表的存储形式

2.图的邻接矩阵存储

(1)无向图:

  • 无向图的邻接矩阵是对称的,是一个对称矩阵
  • 顶点i的度=第i行(列)中1的个数
  • 特别:完全图的邻接矩阵中,对角元素为0,其余为1                                                                                                                                                                                   

(2)有向图:

  • 第i行的含义:顶点vi的出度
  • 第i列的含义:顶点vi的入度
  • 有向图的邻接矩阵可能是不对称的
  • 顶点的出度 = 第i行元素之和
  • 顶点的入度 = 第i列元素之和
#构建无向图的邻接矩阵
class GraphAX():
    def __init__(self,vertex,mat): #vertex为顶点表,mat为边的信息
        self.vertex = vertex
        self.mat = [mat[i][:] for i in range(len(vertex))]
    #求两顶点间是否有边相连
    def get_edge(self,vi,vj):
        if vi not in self.vertex or vj not in self.vertex:
            print("无效顶点")
            return 
        #获取两顶点在顶点表中的索引
        i = self.vertex.index(vi)
        j = self.vertex.index(vj)
        return self.mat[i][j]
    
def create_matrix():
    nodes = ['v0','v1','v2','v3','v4']
    mat = [[0,1,0,1,0],
           [1,0,1,0,1],
           [0,1,0,1,0],
           [1,0,1,0,0],
           [0,1,1,0,0]]
    graph = GraphAX(nodes,mat)
    return graph

if __name__=="__main__":
    graph = create_matrix()
    print(graph.vertex)
    print(graph.mat)
    print(graph.get_edge('v1','v2'))

输出:

有向图绘制转python代码 有向图 python_有向图绘制转python代码

(3)邻接矩阵的优缺点

特点:

  • 统计顶点的度
  • 顶点不变,在图中增加/删除边:将二维数组对应分量赋值1或0
  • 判断任意两个顶点之间是否相连
  • 统计图中有多少条边

缺点:

  • 不便于删除结点
  • 浪费空间,空间复杂度为,是对于稠密图,不对于稀疏图
  • 浪费时间,时间复杂度为

3.图的邻接链表存储:

(1)无向图

#边结点
class Anode():
    def __init__(self,index,weight=0):
        self.index = index
        self.weight = weight
        self.next = None

#顶点
class Vnode():
    def __init__(self,vdata):
        self.vdata = vdata
        self.first = None

class Graph():
    def __init__(self):
        #存放顶点的是一个列表
        self.vnodelist = []
    #添加顶点
    def add_vnode(self,vnodedata):
        vnode = Vnode(vnodedata)
        self.vnodelist.append(vnode)
    #添加边
    def add_edge(self,edgedata1,edgedata2,weight=0):
        #寻找顶点表中是否有edgedata1的结点
        i = 0
        #注意:在while循环结束时,i等于len(self.vnodelist),但是要用for循环的话就到len(self.vnodelist)-1就结束了
        while i < len(self.vnodelist):
            if edgedata1 == self.vnodelist[i].vdata:
                n1 = self.vnodelist[i]
                break
            i += 1
        else:
            if i == len(self.vnodelist):
                self.add_vnode(edgedata1)
            n1 = self.vnodelist[i]              
         #寻找顶点表中是否有edgedata2的结点
        i = 0
        while i < len(self.vnodelist):
            if edgedata2 == self.vnodelist[i].vdata:
                n2 = self.vnodelist[i]
                break
            i += 1
        else:
            if i == len(self.vnodelist):
                self.add_vnode(edgedata2)
            n2 = self.vnodelist[i]  

       #连接顶点与边结点,建立单链表
        j = self.vnodelist.index(n2)
        anode = Anode(j,weight)
        anode.next = n1.first
        n1.first = anode
 
 
graph = Graph()
while True:
    s = input("请输入图的顶点值,当输入!结束")
    if s =="!":
        break
    else:
        graph.add_vnode(s)
while True:
    s1,s2 = input("请输入边的两个结点,用逗号隔开,当输入!结束").split(',')
    if s1 == "!":
        break
    else:
        graph.add_edge(s1,s2)

#打印顶点表中的元素
for i in range(len(graph.vnodelist)):
    print(graph.vnodelist[i].vdata)

输出:

有向图绘制转python代码 有向图 python_邻接矩阵_02

为了测试方便,将输入改成直接构建图。

if __name__ =="__main__": 
    graph = Graph()
    graph.add_vnode("v0")
    graph.add_vnode("v1")
    graph.add_vnode("v2")
    graph.add_vnode("v3")
    graph.add_edge("v0","v1")
    graph.add_edge("v1","v2")
    graph.add_edge("v2","v3")
    graph.add_edge("v3","v4")
    
    #打印顶点表中的元素
    for i in range(len(graph.vnodelist)):
        print(graph.vnodelist[i].vdata,end=',')

输出:

有向图绘制转python代码 有向图 python_邻接矩阵_03