1. 圖
定義:圖(Graph)是由頂點的有窮非空集合和頂點之間邊的集合組成,通常表示為:G(V,E),其中,G表示一個圖,V是圖G中頂點的集合,E是圖G中邊的集合.
簡單點的說:圖由節點和邊組成。一個節點可能與眾多節點直接相連,這些節點被稱為鄰居。
如二叉樹就為一個簡單的圖:
2. 算法
1). 廣度優先搜索:
廣度優先搜索算法(Breadth First Search,BSF),思想是:
- 1.從圖中某頂點v出發,首先訪問定點v
- 2.在訪問了v之后依次訪問v的各個未曾訪問過的鄰接點;
- 3.然后分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於后被訪問的頂點的鄰接點被訪問;
- 4.直至圖中所有已被訪問的頂點的鄰接點都被訪問到;
- 5.如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作為新的起始點,重復上述過程,直至圖中所有頂點都被訪問到為止。
換句話說,廣度優先搜索遍歷圖的過程是以v為起點,由近至遠,依次訪問和v有路徑相通且路 徑長度為1,2...的頂點。
如上圖的BFS訪問順序為:
A->B->C->D->E->F
2). 深度優先搜索:
圖的深度優先搜索(Depth First Search, DFS),和樹的前序遍歷非常類似。
它的思想:
- 1.從頂點v出發,首先訪問該頂點;
- 2.然后依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖;
- 3.直至圖中所有和v有路徑相通的頂點都被訪問到。
- 4.若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重復上述過程,直至圖中所有頂點都被訪問到為止
如上圖的BFS訪問順序為:
A->B->D->E->C->F
3. 代碼
# -*- coding: utf-8 -*-
#/usr/bin/python
from collections import deque
import sys
class Graph(object):
def __init__(self, *args, **kwargs):
self.order = [] #visited order
self.neighbor = {}
def add_node(self, node):
key,val = node
if not isinstance(val, list):
print('node value should be a list')
#sys.exit('failed for wrong input')
self.neighbor[key] = val
def broadth_first(self, root):
if root != None:
search_queue = deque()
search_queue.append(root)
visited = []
else:
print('root is None')
return -1
while search_queue:
person = search_queue.popleft()
self.order.append(person)
if (not person in visited) and (person in self.neighbor.keys()):
search_queue += self.neighbor[person]
visited.append(person)
def depth_first(self, root):
if root != None:
search_queue = deque()
search_queue.append(root)
visited = []
else:
print('root is None')
return -1
while search_queue:
person = search_queue.popleft()
self.order.append(person)
if (not person in visited) and (person in self.neighbor.keys()):
tmp = self.neighbor[person]
tmp.reverse()
for index in tmp:
search_queue.appendleft(index)
visited.append(person)
#self.order.append(person)
def clear(self):
self.order = []
def node_print(self):
for index in self.order:
print(index, end=' ')
if __name__ == '__main__':
g = Graph()
g.add_node(('1',['one', 'two','three']))
g.add_node(('one',['first','second','third']))
g.add_node(('two',['1','2','3']))
g.broadth_first('1')
print('broadth search first:')
print(' ', end=' ')
g.node_print()
g.clear()
print('\n\ndepth search first:')
print(' ', end=' ')
g.depth_first('1')
g.node_print()
print()
ps: 以上代碼需要用python3.x運行,python2.x不支持print的關鍵字參數
PS2: 以上代碼有些許不完善,如果你有改進的方法,請留言,萬分感謝!