廣度優先搜索(Breadth First Search),是很多重要的圖的算法的原型。
重要的作用:遍歷。對於圖的遍歷,一般有以下的基本思想:
①從圖中某個頂點V0出發,並訪問此頂點;
②從V0出發,訪問V0的各個未曾訪問的鄰接點W1,W2,…,Wk;然后,依此從W1,W2,…,Wk
出發訪問各自未被訪問的鄰接點。
③重復②,直到全部頂點都被訪問為止。
【例】如圖1-7,按照廣度優先搜索的思想遍歷這張圖。
正確的方法應該是:
【例】編寫“連連看”的簡單程序
規則是:相連不超過兩個彎的相同圖形是可以消去的。
寫這個程序的時候的基本步驟:
1. 判斷是否能消去
2. 消去/不消去,提示信息
重點應用BFS的是在第一個步驟中:
①圖形是否相等非常簡單,只要判斷該處元素的值即可;
②相連是否不超過兩個彎,我們需要從中取一個結點為起始點,先拿到無須轉彎就能到達的結點集合A,看目標結點是否在里面;如果不在,則需要對結點集合A中所有結點,拿到其無須轉彎就能到達的結點(未在之前訪問過),判斷目標結點是否在內;如果不在,則繼續擴展,這次如果再不在,說明兩結點連接超過兩個彎了,不滿足。
【重點】廣度優先的缺點是:有的時候耗時會很大,這時候可以使用哈希表進行優化。在此不會特別用到,故不再細述。廣度優先搜索與深度有限搜索是兩個相對的搜索方法。對於廣度優先搜索,一般的最短路徑會用到它。
Dijkstra(迪傑斯特拉)算法是典型的單源最短路徑算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法是很有代表性的最短路徑算法,在很多專業課程中都作為基本內容有詳細的介紹,如數據結構,圖論,運籌學等等。注意該算法要求圖中不存在負權邊。
【例】在無向圖 G=(V,E) 中,假設每條邊 E[i] 的長度為 w[i],找到由頂點 V0 到其余各點的最短路徑。(單源最短路徑)例如圖1-8所示:
第一步:先鎖定一個點,這里我用A作為初始的;
第二步:先設A到所有的點的路徑的長度為無窮大,然后按照圖1-9的步驟一步一步做就可以得到答案。
回顧:這里面當選定一個點的時候,就對其可連接到的點進行BFS,所以當問題可以抽象成類似於這個樣子就可以進行BFS進行查找答案(最短路徑)。
這是我從博客園上找到的完整的解題思路供參考:
對於以下的無向圖(圖1-10)進行遍歷
圖1-10 無向圖例題
解答過程見圖1-11.
圖1-11 圖1-10的解答過程
下面是Floyd算法。
Floyd算法是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。Floyd算法的時間復雜度為O(N?)(有點費時間),空間復雜度為O(N?)。
以下的例題和解題過程來自博客園:
基本解題思路:
a.從任意一條單邊路徑開始。所有兩點之間的距離是邊的權,如果兩點之間沒有邊相連,則權為無窮大。
b.對於每一對頂點 u 和 v,看看是否存在一個頂點 w 使得從 u 到 w 再到 v 比己知的路徑更短。如果是更新它。
對於這種題目,我們一般使用的是十字交叉法如圖1-12:
圖1-12 十字交叉法