MATLAB 廣度優先搜索BFS、深度優先搜索DFS


如此經典的算法竟一直沒有單獨的實現過,真是遺憾啊。

廣度優先搜索在過去實現的二值圖像連通區域標記和prim最小生成樹算法時已經無意識的用到了,深度優先搜索倒是沒用過。

這次單獨的將兩個算法實現出來,因為算法本身和圖像沒什么關系,所以更純粹些。

廣度優先搜索是從某一節點開始,搜索與其線連接的所有節點,按照廣度方向像外擴展,直到不重復遍歷所有節點。

深度優先搜索是從某一節點開始,沿着其搜索到的第一個節點不斷深入下去,當無法再深入的時候,回溯節點,然后再在回溯中的某一節點開始沿另一個方向深度搜索,直到不重復的遍歷所有節點。

廣度優先搜索用的是隊列作為臨時節點存放處;深度優先搜索可以遞歸實現(算法導論就是用遞歸實現的偽代碼),不過我這里是用棧作為臨時節點存放處。

感覺也沒什么好介紹的了,抄算法導論上的介紹也沒什么意思,所有的內容都是書上的,真正學東西還是要看書。

下面是運行結果:

原連通圖:

廣度優先搜索:

深度優先搜索:

matlab代碼如下,其中的畫圖函數netplot.m。

BFS.m

 1 clear all;close all;clc  2 %初始化鄰接壓縮表  3 b=[1 2;1 3;1 4;2 4;  4    2 5;3 6;4 6;4 7];  5 
 6 m=max(b(:));                %壓縮表中最大值就是鄰接矩陣的寬與高  7 A=compresstable2matrix(b);  %從鄰接壓縮表構造圖的矩陣表示  8 netplot(A,1)                %形象表示  9 
10 head=1;             %隊列頭 11 tail=1;             %隊列尾,開始隊列為空,tail==head 12 queue(head)=1;      %向頭中加入圖第一個節點 13 head=head+1;        %隊列擴展 14 
15 flag=1;             %標記某個節點是否訪問過了 16 re=[];              %最終結果 17 while tail~=head    %判斷隊列是否為空 18     i=queue(tail);  %取隊尾節點 19     for j=1:m 20         if A(i,j)==1 && isempty(find(flag==j,1))    %如果節點相連並且沒有訪問過 21             queue(head)=j;                          %新節點入列 22             head=head+1;                            %擴展隊列 23             flag=[flag j];                          %對新節點進行標記 24             re=[re;i j];                            %將邊存入結果 25  end 26  end 27     tail=tail+1; 28 end 29 
30 A=compresstable2matrix(re); 31 figure; 32 netplot(A,1)

DFS.m

 1 clear all;close all;clc  2 %初始化鄰接壓縮表  3 b=[1 2;1 3;1 4;2 4;  4    2 5;3 6;4 6;4 7];  5 
 6 m=max(b(:));                %壓縮表中最大值就是鄰接矩陣的寬與高  7 A=compresstable2matrix(b);  %從鄰接壓縮表構造圖的矩陣表示  8 netplot(A,1)                %形象表示  9 
10 top=1;                  %堆棧頂 11 stack(top)=1;           %將第一個節點入棧 12 
13 flag=1;                 %標記某個節點是否訪問過了 14 re=[];                  %最終結果 15 while top~=0            %判斷堆棧是否為空 16     pre_len=length(stack);    %搜尋下一個節點前的堆棧長度 17     i=stack(top);             %取堆棧頂節點 18     for j=1:m 19         if A(i,j)==1 && isempty(find(flag==j,1))    %如果節點相連並且沒有訪問過 20             top=top+1;                          %擴展堆棧 21             stack(top)=j;                       %新節點入棧 22             flag=[flag j];                      %對新節點進行標記 23             re=[re;i j];                        %將邊存入結果 24             break; 25  end 26  end 27     if length(stack)==pre_len   %如果堆棧長度沒有增加,則節點開始出棧 28         stack(top)=[]; 29         top=top-1; 30  end 31 end 32 
33 A=compresstable2matrix(re); 34 figure; 35 netplot(A,1)

compresstable2matrix.m

 1 function A=compresstable2matrix(b)  2     [n ~]=size(b);  3     m=max(b(:));  4     A=zeros(m,m);  5 
 6     for i=1:n  7         A(b(i,1),b(i,2))=1;  8         A(b(i,2),b(i,1))=1;  9  end 10 
11 end

 


免責聲明!

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



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