算法導論(MIT 6.006 第13講)算法
搜索能夠理解爲探索,給定一個圖上的點S和A,須要找到從S到A的一個路徑數組
一個圖用 G=(V,E)
表示,V是頂點的集合,E是邊的集合。以下所示有兩種圖網絡
網絡爬蟲、社交網絡、網絡包傳播、垃圾回收算法等app
使用鄰接表。它是一個數組(Adj表示)大小是 |V|,每一個元素是指向一個鏈表的指針,遍歷的方法以下spa
for each vertex u in V Adj[u] stores u's neighbors
好比,上所述的有向圖來講 Adj[a]={b},Adj[b]={a,c}
,對無向圖來說 Adj[a]={(a,c),(a,b)}
指針
這種表現形式所須要的空間大小爲 $\Theta$(V+E),|V|個頂點和|E|條邊
目標:對於一個給定的節點S $\in$V,經過它來遍歷它所能到達的全部節點
時間要求:O(V+E)
思路:查看給定節點,經過0步移動,可以到達的節點,這個節點就是s自己,而後從s移動一步,也就是s的鄰接表,找到他能到達的節點,依次類推,須要避免重複code
BFS(s,Adj): level={s:0} //第0步能到達的節點 parent={s:None} i=1 //第0步就是s,已經到達,從第一步開始 frontier=[s] //前一層已經通過的節點 level=i-1 while frontier: //在已經通過的節點找它的相鄰節點 next=[] //當前層找到的節點 for u in frontier: for v in Adj[u]: if v not in level: //當前節點沒有在其它層出現過,從而避免重複 level[v]=i parent[v]=u next.append(v) frontier=next i+=1 //走下一層
以無向圖爲例圖片
level={s:0,a:1,x:1} parent={s:None,a:s,x:s} frontier={a,s} i=2
level={s:0,a:1,x:1,z:2,x:2} parent={s:None,a:s,x:s,z:a,d:x,c:x} frontier={z,d,c} i=3
level={s:0,a:1,x:1,z:2,x:2,f:3,v:3} parent={s:None,a:s,x:s,z:a,d:x,c:x,f:d,v:c} frontier優先存的是d frontier={f,v} i=4
frointer={} i=5
至此結束it
BFS所作的策略是先找到每一層的節點,再去找它的鄰接表,耗時能夠從兩部分來看,1個是必須遍歷全部節點,爲V,另外每一層遍歷的邊的數量爲 $\sum$v$\in$V$|Adj[v]|$,即每一個頂點的邊的個數,對於有向圖來說是E,無向圖就是2E,這樣總的時間就是 $\theta$(V+E)class