图的基础-python


前言

随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了python数据结构图的基础内容。


一、图的基本概念

二、图的存储结构

1.邻接矩阵(MatGraph)

代码如下(示例):

import copy
INF=0x3f3f3f  #表示无穷大
class MatGraph:
    def __init__(self,n=0,e=0):
        self.edges=[]  #邻接矩阵
        self.vexs=[]
        self.n=n    #顶点数
        self.e=e    #边数
    def CreateMatGraph(self,a,n,e):
        self.n=n
        self.e=e
        self.edges=copy.deepcopy(a)
    def DisMatGraph(self):
        for i in range(self.n):
            for j in range(self.n):
                if self.edges[i][j]==INF:
                    print("%4s"%("∞"),end='')
                else:
                    print("%4s"%(self.edges[i][j]),end='')
            print()
def Degree1(g,v):  #在无向图中求顶点V的度
    d=0
    for i in range(g.n):
        if g.edges[v][i]!=INF:
            d+=g.edges[v][i]
    return d
def Degree2(g,v):  #在有向图中求顶点v的度
    d=[0,0]
    for i in range(g.n):
        if g.edges[v][i]!=INF:
            d[0]+=g.edges[v][i]
    for j in range(g.n):
        if g.edges[j][v]!=INF:
            d[1]+=g.edges[j][v]
    return d[0]+d[1]
m=MatGraph()
a=[
    [1,1,1],
    [1,0,1],
    [0,0,1]
]
m.CreateMatGraph(a,3,3)
m.DisMatGraph()
print(Degree1(m,0))
print(Degree2(m,0))

2.邻接表(AdjGraph)

邻接表每一行表示一个顶点,这一行,表示存放该顶点的所有邻接点以及他们之间的权值。适用于稀疏图和稠密图。
代码如下(示例):

INF=0x3f3f3f
class ArcNode:   #边节点类
    def __init__(self,adjv,w):
        self.adjvex=adjv    #一个边结点包括两个东西,邻接点以及权值
        self.weight=w
class AdjGraph:
    def __init__(self,n,e):
        self.adjlist=[]  #邻接表
        self.vexs=[]    #存放顶点信息暂时未用
        self.n=n  #顶点数
        self.e=e  #边数
    def CreateAdjGraph(self,a,n,e):  #创建邻接表
        self.n=n
        self.e=e
        for i in range(n):
            adi=[]
            for j in range(n):
                if a[i][j]!=0 and a[i][j]!=INF:
                    p=ArcNode(j,a[i][j])
                    adi.append(p)
            self.adjlist.append(adi)
    def DisAdjGraph(self):
        for i in range(self.n):
            print(" [%d]"%(i),end='')
            for p in self.adjlist[i]:
                print("->(%d,%d)"%(p.adjvex,p.weight),end='')
            print("-^")
def Degree1(g,v):    #求无向图中顶点v的度
    return len(g.adjlist[v])
def Degree2(g,v):  #有向图中求顶点v的度
    d=[0,0]
    d[0] += len(g.adjlist[v])  # 出度
    for i in range(g.n):
        for p in g.adjlist[i]:   #遍历邻接表中的每一个邻接点,如果某一个顶点的邻接点等于v,那么为v的入度之一,循环相加得到v的入度
            if p.adjvex==v:
                d[1]+=p.weight  #书上说是+=1,应该是不考虑有权值
                break
    return d[0]+d[1]
m=AdjGraph(3,3)
a=[
    [1,1,1],
    [1,0,1],
    [0,1,1]
]
m.CreateAdjGraph(a,3,3)
m.DisAdjGraph()
print(Degree1(m,1))
print(Degree2(m,1))

三、图的遍历

1.深度优先(DFS)

1-1采用邻接表的存储方式
MAXV=100   #全局变量表示最多的顶点数
visited=[0]*MAXV
#以邻接表的方式进行存储
def DFS1(G,v):
    print(v,end='')
    visited[v]=1
    for j in range(len(G.adjlist[v])):
        w=G.adjlist[v][j].adjvex
        if visited[w]==0:
            DFS1(G,w)
#方式二
def DFS2(G,v):
    print(v,end='')
    visited[v]=1
    for p in G.adjlist[v]:
        w=p.adjvex
        if visited[w]==0:
            DFS2(G,w)
1-2采用邻接矩阵的存储
#当用邻接矩阵的方式进行存储时
MAXV=100
visited=[0]*MAXV
def DFS_Mat(G,v):
    print(v,end='')
    visited[v]=1
    for w in range(G.n):
        if G.edges[v][w]!=0 and G.edges[v][w]!=INF:
            if visited[w]==0:
                DFS_Mat(G,w)

2.广度优先 (BFS)

2-1存储结构为邻接表
from collections import deque
MAXV=100
visited=[0]*MAXV
def BFS(G,v):
    print(v,end=" ")
    qu=deque()
    visited[v]=1  #该邻接点被访问,所以标记为1
    qu.append(v)  #进行入队
    while len(qu)>0:   #当队列不为空执行
        v=qu.popleft()  #进行出队,一遍后面用来将这个顶点找邻接点
        for j in range(len(G.adjlist[v])):  #遍历顶点v的所有邻接点
            w=G.adjlist[v][j].adjvex
            if visited[w]==0:
                print(w,end=" ")
                visited[w]=1
                qu.append(w)
2-2存储结构为邻接矩阵
#邻接矩阵为存储结构时
def BFS_Mat(G,v):
    qu=deque()
    print(v,end=" ")  #进行遍历
    visited[v]=1   #遍历完了标记为1
    qu.append(v)
    while len(qu)>0:
        v=qu.popleft()
        for w in range(G.n):    #遍历v的所有邻接点
            if G.edges[v][w]!=0 and G.edges[v][w]!=INF:
                if visited[w]==0:
                    print(w,end=" ")
                    visited[w]=1
                    qu.append(w)

四、非连通图的遍历

4-1 非连通图的DFS
#非连通图的DFS,邻接表存储的图
def DFSA(G):
    for i in range(G.n):  #遍历图中的每一个顶点
        if visited[i]==0:  #查看每一个顶点是否访问
            DFS1(G,i)   #没有访问,则进行深度优先遍历,这样可以保证非连通图也可以对每一个节点进行访问
4-2 非连通图的BFS
#非连通图的BFS
def BFSA(G):
    for i in range(G.n):
        if visited[i]==0:
            BFS(G,i)
例题

判断一个无向图是不是连通图

#例题
def DFS_1(G,v):
    visited[v]=1
    for i in range(len(G.adjlist[v])):
        w=G.adjlist[v][i].adjvex
        if visited[w]==0:
            DFS_1(G,w)
def Connext(G):
    flag=True
    DFS_1(G,0)  #传入一个点,进行深度优先遍历,如果一个图是连通的那么它一定会全部遍历得到
    for i in range(G.n):  
        if visited[i]!=0:  #如果存在顶点未被访问的话则不连通
            flag=False
            break
    return flag

总结

图的深度优先遍历算法类似于树的先序遍历,宽度优先则类似于层次遍历,深度优先利用递归,广度优先运用队列,熟悉图的基本概念。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值