圖
雖然樹很靈活,並且有很多不同的應用,但是樹本身存在侷限,樹只能表示層次關係。圖是樹的推廣,在這一數據結構中不存在那麼多的限制。圖是由節點和頂點間的關係組成的集合。圖是一種多用途的數據結構,可以表示多種情況。
簡單的圖G = (V,E)由非空頂點集V和邊集合E組成。每條邊都是V中兩個定點的集合。頂點和邊的數量分別用 |V| 和 |E| 表示。無向圖中,邊的形式爲{Vij,Vji},且{Vji,Vij}={Vij,Vji},有向圖中這種關係則不成立。一般情況下,我們記兩個頂點之間的邊爲edge(Vi,Vj)。
如果每條邊都附帶有數值,則稱之爲加權圖。如果任意兩個頂點之間都有一條邊將其連接起來,則稱之爲完全圖。
圖的鄰接矩陣法表示 ,:如果存在邊edge(Vi,Vj),則aij = 1(有向圖中等於權值);否則aij = 0。如下圖所示
圖的遍歷
和樹的遍歷相同,圖的遍歷操作也是對圖中的每個節點只訪問一次。簡單的樹的遍歷算法不能應用在圖上,因爲圖可能會包含循環,直接使用樹的遍歷算法就很有可能進入死循環。爲了防止死循環,可以給已訪問過的節點做一個標記,避免重複訪問。
圖的深度優先查找,先訪問頂點V,再訪問與頂點V鄰接的未訪問頂點。如果頂點V沒有鄰接頂點或者爲訪問過的頂點,則回溯到頂點V的前驅節點。如果回到了遍歷開始的第一個頂點,則遍歷結束。
除此之外,圖也有相應的廣度優先搜索,同樣也需要添加檢驗節點是否被訪問過的操作。
圖的python實現
from collections import deque
class Graph(object):
def __init__(self):
self.order = []
self.neighbor = {}
def add_node(self, node):
key, val = node
if not isinstance(val, list):
print('node value should be a list')
self.neighbor[key] = val
def bfs(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 dfs(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)
def clear(self):
self.order = []
def node_print(self):
for index in self.order:
print(index, end=' ')
歡迎關注公衆號 : 數學算法實驗室
算法與人工智能