前言算法
這幾天複習圖論算法,以爲BFS和DFS挺重要的,並且應用比較多,故記錄一下。數據結構
廣度優先搜索網站
有一個有向圖如圖aspa
圖a.net
廣度優先搜索的策略是:3d
從起始點開始遍歷其鄰接的節點,由此向外不斷擴散。code
1.假設咱們以頂點0爲原點進行搜索,首先肯定鄰接0的頂點集合S0 = {1,2}。blog
2.而後肯定頂點1的集合S1 = {3},頂點2沒有鄰接點,因此集合爲空。隊列
3.而後肯定3的鄰接點集合S3,由於2已經被遍歷過,因此不考慮,因此由頂點3知道的鄰接點集合S3 = {4}。ip
4.而後再肯定頂點4的鄰接點集合,頂點4沒有更多的鄰接點了,此時也沒有還未遍歷的鄰接點集合,搜索終止。
遍歷的路徑能夠參考以下圖紅色標記的路徑:
動態過程
代碼的實現思路:
BFS()
{
輸入起始點; 初始化全部頂點標記爲未遍歷; 初始化一個隊列queue並將起始點放入隊列; while(queue不爲空) {
從隊列中刪除一個頂點s並標記爲已遍歷; 將s鄰接的全部還沒遍歷的點加入隊列; }
}
深度優先遍歷
繼續以圖a爲例
圖a
深度優先遍歷的策略是:
從一個頂點v出發,首先將v標記爲已遍歷的頂點,而後選擇一個鄰接於v的還沒有遍歷的頂點u,若是u不存在,本次搜素終止。若是u存在,那麼從u又開始一次DFS。如此循環直到不存在這樣的頂點。
好比圖a中
1.從頂點0開始,將0標記爲已遍歷,而後選擇未被遍歷的鄰接0的頂點1。
2.標記頂點1,而後選擇3並標記,而後選擇頂點3鄰接的頂點2。
3.頂點2標記後沒有與它鄰接的未標記的點,因此返回3選擇另外一個鄰接3而且未被標記的頂點4。
4.頂點4沒有更多的符合條件的點,所以搜索終止,返回到3,3沒有更多的點,搜索終止返回到1,最後返回到0,搜索終止。
遍歷的路徑能夠參考以下圖紅色標記的路徑:
動態過程
代碼的實現思路:
DFS(頂點v) { 標記v爲已遍歷; for(對於每個鄰接v且未標記遍歷的點u) DFS(u); }
一個簡單的應用
問題不贅述,具體可參考 LeetCode朋友圈問題 。
實現的代碼以下(C#):
public class Solution { public void dfs(int [,]M,int []visit,int i) { for(int j = 0;j < M.GetLength(0);j++) { if(M[i,j] == 1 && visit[j] == 0) { visit[j] = 1; dfs(M,visit,j); } } } public void bfs(int [,]M,int []visit,int i) { Queue<int> q = new Queue<int>(); q.Enqueue(i); while(q.Count > 0) { int temp = q.Dequeue(); for(int j = 0;j < M.GetLength(0);j++) { if(M[temp,j] == 1 && visit[j] == 0) { visit[j] = 1; q.Enqueue(j); } } } } public int FindCircleNum(int[,] M) { int N = M.GetLength(0); int circle = 0; //朋友圈數 int[] visit = new int[N]; for(int i = 0;i < N;i++) { if(visit[i] == 0) //還沒被遍歷過 { //dfs(M,visit,i); //使用dfs搜索並標記與其相關的學生 bfs(M,visit,i); //使用bfs搜索並標記與其相關的學生 circle++; } } return circle; } }
參考資料
《數據結構、算法與應用——C++描述》 做者:【美】 薩特吉·薩尼 機械工業出版社