數據結構和算法總結(一):廣度優先搜索BFS和深度優先搜索DFS


前言

這幾天復習圖論算法,覺得BFS和DFS挺重要的,而且應用比較多,故記錄一下。

廣度優先搜索

有一個有向圖如圖a

 

                                                   圖a

 

 

廣度優先搜索的策略是:

從起始點開始遍歷其鄰接的節點,由此向外不斷擴散。

1.假設我們以頂點0為原點進行搜索,首先確定鄰接0的頂點集合S0 = {1,2}。

2.然后確定頂點1的集合S1 = {3},頂點2沒有鄰接點,所以集合為空。

3.然后確定3的鄰接點集合S3,因為2已經被遍歷過,所以不考慮,所以由頂點3知道的鄰接點集合S3 = {4}。

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++描述》   作者:【美】 薩特吉·薩尼       機械工業出版社

  Visualgo算法可視化網站


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM