思路:
1、递归DFS:访问节点,将该节点标记为已访问,同时对根节点的邻接结点中未访问过的结点递归调用DFS
2、非递归DFS:取栈顶元素(不出栈),找到栈顶元素的一个未被访问过的邻接结点(注意是一个就行,不需要所有邻接结点入 栈,与BFS不同),访问、标记为已访问并入栈,直到栈顶元素的所有邻接结点都被访问过,栈顶元素出栈,直到栈空
3、BFS:采用队列的数据结构,取队列首元素,将该节点标记为已访问,将该节点的未被访问过且不在队列中的邻接结点加入队 列中
代码如下:
# -*- coding:utf-8 -*-\
# *args 把参数打包成tuple供函数调用。**kwargs把 x = a,y=b打包成字典{x:a,y:b}供函数调用
class Graph(object):
def __init__(self, *args, **kwargs):
self.node_neighbors = {}
self.visited = {}
def add_nodes(self, nodelist):
for node in nodelist:
self.add_node(node)
def add_node(self, node):
if not node in self.nodes():
self.node_neighbors[node] = []
def add_edge(self, edge):
u, v = edge
if (v not in self.node_neighbors[u]) and (u not in self.node_neighbors[v]):
self.node_neighbors[u].append(v)
if (u != v):
self.node_neighbors[v].append(u)
def nodes(self):
return self.node_neighbors.keys()
#递归DFS
def depth_first_search(self,root=None):
order=[]
def dfs(node):
self.visited[node] = True
order.append(node)
for n in self.node_neighbors[node]:
if not n in self.visited:
dfs(n)
if root:
dfs(root)
#对于不连通的结点(即dfs(root)完仍是没有visit过的单独处理,再做一次dfs
for node in self.nodes():
if not node in self.visited:
dfs(node)
self.visited = {}
print order
return order
#非递归DFS
def depth_first_search2(self,root=None):
stack = []
order = []
#self.visited[root] = True
def dfs():
while stack:
node = stack[-1]
for n in self.node_neighbors[node]:
if not n in self.visited:
order.append(n)
stack.append(n)
self.visited[n] = True
break
else:
stack.pop()
if root:
stack.append(root)
order.append(root)
self.visited[root]=True
dfs()
for node in self.nodes():
if node not in self.visited:
stack.append(node)
order.append(node)
self.visited[node]=True
dfs()
self.visited = {}
print order
return order
def breadth_first_search(self,root=None):
queue = []
order = []
def bfs():
while len(queue)>0:
node = queue.pop(0)
self.visited[node] = True
for n in self.node_neighbors[node]:
if (not n in self.visited) and (not n in queue):
queue.append(n)
order.append(n)
if root:
queue.append(root)
order.append(root)
bfs()
for node in self.nodes():
if not node in self.visited:
queue.append(node)
order.append(node)
bfs()
self.visited = {}
print order
return order
if __name__ == '__main__':
g = Graph()
g.add_nodes([i + 1 for i in range(8)])
g.add_edge((1, 2))
g.add_edge((1, 3))
g.add_edge((2, 4))
g.add_edge((2, 5))
g.add_edge((4, 8))
g.add_edge((5, 8))
g.add_edge((3, 6))
g.add_edge((3, 7))
g.add_edge((6, 7))
print "nodes:", g.nodes()
print "BFS:"
order = g.breadth_first_search(1)
# self.visited 在经历了一次bfs之后已经有了值,如果dfs直接进行,就会发生只输出结点1的情况
print "递归DFS:"
order = g.depth_first_search(1)
print "非递归DFS"
order = g.depth_first_search2(1)