图的存储
图的存储分为邻接矩阵和邻接表,其中对于稀疏图邻接表的存储效率更高,对于稠密图邻接矩阵存储效率跟高。这里的BFS和DFS是基于邻接表实现,所以有关邻接矩阵的存储可以查阅百度百科。
邻接点主要包括两部分:顶点和邻接点,顶点包括顶点信息和指向第一个邻接点的指针(python中使用元组模拟)。邻接点包括邻接点的存储下标和指向下一节点的指针。(python中使用列表模拟),顶点 V i V_i Vi的所有邻接点构成一个列表。
- 目前电脑还没找到比较合适的画图工具,只能手机拍照了。
图的遍历
广度优先搜索,又称宽度优先搜索。广度优先搜索是从某个顶点(源点)出发,一次性访问所有未被访问的邻接点,再依次从这些访问过的邻接点出发进行搜索。
- 广度优先遍历秘籍:先被访问的顶点,其邻接点先被访问。采用队列的形式实现
深度优先搜索沿着一条路径一直走下去,无法行进时,回退到刚刚访问的节点。深度优先遍历是按照深度优先搜索的方式对图进行遍历。
- 深度优先遍历秘籍:后被访问的顶点,其邻接点先被访问。采用递归的方式实现。
python实现
# coding=utf-8
from queue import Queue
# Definition for a Node.
class Node:
def __init__(self, val):
self.val = val
self.next = None
class Solution(object):
"""
根据邻接表创建有向图
"""
def __init__(self,adj_list):
self.adj_list = adj_list
self.peaks = []
self.visited = [False]*len(self.adj_list)
def bfs(self):
"""
广度优先遍历,时间复杂度O(n)
:return:
"""
queue = Queue()
self.visited = [False]*len(self.adj_list) # 存储顶点的访问状态
queue.put(0) # 默认从邻接表第0个邻接点开始
self.visited[0] = True
self.peaks = self.adj_list[0][0]
while not queue.empty():
index = queue.get() # 出队
for i in self.adj_list[index][1]:
if not self.visited[i]: # 判断是否被访问
self.visited[i] = True
queue.put(i) # 入队
self.peaks.append(adj_list[i][0])
print(self.visited)
return self.peaks
def dfs(self,node):
"""
递归调用深度优先遍历,时间复杂度O(n)
:return:
"""
self.visited[node] = True
self.peaks.append(self.adj_list[node][0])
for index in self.adj_list[node][1]:
# 判断该节点是否被访问过
if not self.visited[index]:
self.dfs(index)
# print(index)
return self.peaks
if __name__ == '__main__':
# 邻接表表示有向图
adj_list = [
("a",[4,2,1]),
("b",[2]),
("c",[4,3]),
("d",[4]),
("e",[]),
]
solution = Solution(adj_list)
# print(solution.bfs())
print(solution.dfs(0))
```