图的基本概念
图的表示法
- 邻接表法
n个链表,链接到的点表示可以可以一次到达的点 - 临接矩阵法
一个正方形矩阵,n行n列,二维矩阵值表示距离,无穷表示无路
学习时候,只需要针对一种表示法,熟记所有方法,在对不同题时,将输入转换成你使用的表示法,再进行算法即可。
图的入度和出度
- 入度
指向该点的所有边 - 出度
该点指出的所有边
针对无向图:入度=出度
图的遍历
宽度优先遍历
def bfs(node):
if node is None:
return
queue = [node] # 队
se = {node:1} # 确保不重复
while len(queue):
cur = queue.pop()
print(cur.val) # 行为处理
for nx in cur.nexts: # 所有下一个边
if nx not in se: # 如果点没有遍历
se[nx] = 1 # 加上这个点
queue += [nx]
深度优先遍历
def dfs(node):
if node is None:
return
stack = [node] # 栈
se = {node:1} # 确保不重复
print(node.val)
while len(stack):
cur = stack.pop()
for nx in cur.nexts: # 所有下一个边
if nx not in se: # 如果点没有遍历
stack += [cur]
stack += [nx]
se[nx] = 1 # 记录这个点
print(ne.val)
break
图的算法
拓扑排序
leetcode 113题
def topologySort(graph):
hs = {} # key是点,value是甚于的入度
que = [] # 队,存所有入度为0的点
for node in graph.nodes.values():
hs[node] = node.ind # ind为入度
if node.ind == 0:
que.append(node)
res = [] # 存拓扑排序的结果
while len(que):
cur = que.pop(0) # 队的第一个元素
res += [cur]
for nx in cur.nexts:
hs[nx] = hs[nx] - 1 # 入度减1
if hs[nx] == 0:
que.append(nx)
return res
Kruskal算法,生成最小生成树
- 思路,所有边先排序
- 每次挑选最小的边,如果加上不形成环,就选择该点
- 使用并查集
Prim算法,生成最小生成树
- 思路,从任一点出发
- 每次挑选可以到达的所有边的最小边(新边的两点没有选过),每次加新点,新边,一直到点选完
- 代码待完善,有的不对
def primeMST(graph):
sta = [] # 定义一个小根堆,这里不对,以后再改
node = {}
res = [] # 返回的结果,依次挑选的边
for no in graph.nodes.values():
if no not in node:
node[no] = 1 # 添加
for edge in no.edges:
sta.add(edge)
while len(sta):
edge = sta.pop() # 弹出最小的边
tonode = edge.to
if tonode not in node:
node[tonode] = 1
res.append(edge)
for nxed in tonode.edges:
sta.add(nxed)
return res