图论

图的分类

在这里插入图片描述

存图方式

1.邻接矩阵
空间复杂度一般为n*n一般不用。
2.邻接表(主要)
3.链式前向星(主要)
无向图的存储相比右向图,需要双向加边。

图的遍历

一、DFS(深度优先搜索)
遍历思想:基本思想:首先从图中某个顶点v0出发,访问此顶点,然后依次从v相邻的顶点出发深度优先遍历,直至图中所有与v路径相通的顶点都被访问了;若此时尚有顶点未被访问,则从中选一个顶点作为起始点,重复上述过程,直到所有的顶点都被访问。
深度优先遍历用递归实现比较简单,只需用一个递归方法来遍历所有顶点,在访问某一个顶点时:
1.将它标为已访问
2.递归的访问它的所有未被标记过的邻接点
通过一个栈来保证

#深度优先遍历
graph = {"A":["B","C"],
         "B":["A","C","D"],
         "C":["A","B","D","E"],
         "D":["B","C","E","F"],
         "E":["C","D"],
         "F":["D"],
         }  #用一个字典保存图
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 i in nodes:
            if i not in seen:
                stack.append(i)
                seen.add(i)
        print(vertex)
                
DFS(graph,"A")  

二、BFS(广度优先搜索)
**遍历思想:**首先,从图的某个顶点v0出发,访问了v0之后,依次访问与v0相邻的未被访问的顶点,然后分别从这些顶点出发,广度优先遍历,直至所有的顶点都被访问完。

在这里插入图片描述

#广度优先遍历
graph = {"A":["B","C"],
         "B":["A","C","D"],
         "C":["A","B","D","E"],
         "D":["B","C","E","F"],
         "E":["C","D"],
         "F":["D"],
         }  #用一个字典保存图
def BFS(graph,s):  #s代表起始点
    queue=[]  #用数组代替一个队列
    queue.append(s)
    seen=set()  #集合,存储已经访问过的节点
    seen.add(s)
    while (len(queue)>0):
        vertex=queue.pop(0)
        nodes=graph[vertex]
        for i in nodes:
            if i not in seen:
                queue.append(i)
                seen.add(i)
        print(vertex)
                
BFS(graph,"F")  

有权图的最短路径

可以由** [优先队列]**解决 链接:(https://www.jianshu.com/p/b51ab28ca8dd).
对下图进行操作:

在这里插入图片描述首先将A放入队列中,A到A的距离为0,将拿出,再同时放入B、C,因为(B,5)的优先级低于(C,1),交换B、C的顺序。再将C拿出,在插入C的邻接点D、E,此时他们的优先级分别为(D,5),(E,9).后面数字分别为A到D、E的距离
在这里插入图片描述
在这里插入图片描述
最终得到如下:
在这里插入图片描述
代码实现过程如下:(以A为起始点)

import heapq  #优先队列
import math


#heapq.heappush(pqueue,(1,'A'))#A的权限是1
graph = {"A":{"B":5,"C":1},
         "B":{"A":5,"C":2,"D":1},
         "C":{"A":1,"B":2,"D":4,"E":8},
         "D":{"B":1,"C":4,"E":3,"F":6},
         "E":{"C":8,"D":3},
         "F":{"D":6}
         } 

      
def init_distance(graph,s):
    distance={s:0}
    for vertex in graph:
        if vertex != s:
            distance[vertex]=math.inf
    return distance
            
def dijkstra(graph,s):  #s代表起始点
    pqueue=[]  #用数组代替一个队列
    heapq.heappush(pqueue,(0,s))#A的权限是1
    seen=set()  #集合,存储已经访问过的节点
    
    parent={s:None}   #保存上一个节点
    distance=init_distance(graph,s)   #初始化距离
    #将第一个距离设为0,同时把其他的设为正无穷   init_distance
    while (len(pqueue)>0):
        pair=heapq.heappop(pqueue)#有两个内容
        dist=pair[0]
        vertex=pair[1]
        seen.add(vertex) #拿出来后才确定该节点被访问过
        nodes=graph[vertex].keys()
        for i in nodes:
            if i not in seen:
                if dist + graph[vertex][i]<distance[i]:
                    heapq.heappush(pqueue,(dist+graph[vertex][i],i))
                    #如过没有出现,需要计算距离
                    parent[i]=vertex
                    distance[i]=dist+graph[vertex][i]
    return parent,distance
parent,distance=dijkstra(graph,"A")
print(parent)
print(distance)

输出结果如下:
在这里插入图片描述
与分析结果一致。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值