目录
首先,必须要记录的就是,这都是再图结构以及建构好的前提下进行的,直接将graph作为输入来进行搜索的。
代码详解
利用队列,构造一种从起始节点开始,由近到远的一种访问,
广度优先搜索(BFS)
下面定义一个bfs的类,图作为一个参数,先初始化一个访问一个队列search_queue,往队列里面push图点,只要队列不为空,就继续操作,将队列里面的值逐一的给取出进行访问,然后,添加到一个已经访问的节点中去。接下来做的就是(最底下的那个for循环)将节点的连接图全部添加进去,这样就能实现先访问它,再访问它邻居,再访问它邻居的邻居。由近到远的访问。
def bfs(graph, start):
search_queue = Queue()
search_queue.push(start)
searched = set()
while search_queue: # 队列不为空就继续
cur_node = search_queue.pop()
if cur_node not in searched:
print(cur_node)
searched.add(cur_node)
for node in graph[cur_node]:
search_queue.push(node)
深度优先搜索(DFS)
如果访问一个节点,如果没有访问过,就直接去访问它的邻居,而不是放到队列里面,是不断加深的。用递归来实现。
先定义一个全局变量DFS_SEARCHED,作为记录访问过的节点。那么开始从第一个节点开始,开始不断递归来访问每访问过的点。
DFS_SEARCHED = set()
def dfs(graph, start):
if start not in DFS_SEARCHED:
print(start)
DFS_SEARCHED.add(start)
for node in graph[start]:
if node not in DFS_SEARCHED:
dfs(graph, node)
完整代码
# -*- coding: utf-8 -*-
from collections import deque
GRAPH = {
'A': ['B', 'F'],
'B': ['C', 'I', 'G'],
'C': ['B', 'I', 'D'],
'D': ['C', 'I', 'G', 'H', 'E'],
'E': ['D', 'H', 'F'],
'F': ['A', 'G', 'E'],
'G': ['B', 'F', 'H', 'D'],
'H': ['G', 'D', 'E'],
'I': ['B', 'C', 'D'],
}
class Queue(object):
def __init__(self):
self._deque = deque()
def push(self, value):
return self._deque.append(value)
def pop(self):
return self._deque.popleft()
def __len__(self):
return len(self._deque)
def bfs(graph, start):
search_queue = Queue()
search_queue.push(start)
searched = set()
while search_queue: # 队列不为空就继续
cur_node = search_queue.pop()
if cur_node not in searched:
print(cur_node)
searched.add(cur_node)
for node in graph[cur_node]:
search_queue.push(node)
print('bfs:')
bfs(GRAPH, 'A')
DFS_SEARCHED = set()
def dfs(graph, start):
if start not in DFS_SEARCHED:
print(start)
DFS_SEARCHED.add(start)
for node in graph[start]:
if node not in DFS_SEARCHED:
dfs(graph, node)
print('dfs:')
dfs(GRAPH, 'A')
class Stack(object):
def __init__(self):
self._deque = deque()
def push(self, value):
return self._deque.append(value)
def pop(self):
return self._deque.pop()
def __len__(self):
return len(self._deque)
def dfs_use_stack(graph, start):
stack = Stack()
stack.push(start)
searched = set()
while stack:
cur_node = stack.pop()
if cur_node not in searched:
print(cur_node)
searched.add(cur_node)
# 请读者思考这里我为啥加了 reversed,其实不加上是可以的,你看下代码输出
for node in reversed(graph[cur_node]):
stack.push(node)
print('dfs_use_stack:')
dfs_use_stack(GRAPH, 'A')