matlab練習程序(廣度優先搜索BFS、深度優先搜索DFS)


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

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

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

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

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

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

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

下面是運行結果

原連通圖:

廣度優先搜索:

深度優先搜索:

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

BFS.m

clear all;close all;clc
%初始化鄰接壓縮表
b=[1 2;1 3;1 4;2 4;
   2 5;3 6;4 6;4 7];

m=max(b(:));                %壓縮表中最大值就是鄰接矩陣的寬與高
A=compresstable2matrix(b);  %從鄰接壓縮表構造圖的矩陣表示
netplot(A,1)                %形象表示

head=1;             %隊列頭
tail=1;             %隊列尾,開始隊列為空,tail==head
queue(head)=1;      %向頭中加入圖第一個節點
head=head+1;        %隊列擴展

flag=1;             %標記某個節點是否訪問過了
re=[];              %最終結果
while tail~=head    %判斷隊列是否為空
    i=queue(tail);  %取隊尾節點
    for j=1:m
        if A(i,j)==1 && isempty(find(flag==j,1))    %如果節點相連並且沒有訪問過
            queue(head)=j;                          %新節點入列
            head=head+1;                            %擴展隊列
            flag=[flag j];                          %對新節點進行標記
            re=[re;i j];                            %將邊存入結果
        end
    end
    tail=tail+1;            
end

A=compresstable2matrix(re);
figure;
netplot(A,1)

DFS.m

clear all;close all;clc
%初始化鄰接壓縮表
b=[1 2;1 3;1 4;2 4;
   2 5;3 6;4 6;4 7];

m=max(b(:));                %壓縮表中最大值就是鄰接矩陣的寬與高
A=compresstable2matrix(b);  %從鄰接壓縮表構造圖的矩陣表示
netplot(A,1)                %形象表示

top=1;                  %堆棧頂
stack(top)=1;           %將第一個節點入棧

flag=1;                 %標記某個節點是否訪問過了
re=[];                  %最終結果
while top~=0            %判斷堆棧是否為空
    pre_len=length(stack);    %搜尋下一個節點前的堆棧長度
    i=stack(top);             %取堆棧頂節點
    for j=1:m
        if A(i,j)==1 && isempty(find(flag==j,1))    %如果節點相連並且沒有訪問過 
            top=top+1;                          %擴展堆棧
            stack(top)=j;                       %新節點入棧
            flag=[flag j];                      %對新節點進行標記
            re=[re;i j];                        %將邊存入結果
            break;   
        end
    end    
    if length(stack)==pre_len   %如果堆棧長度沒有增加,則節點開始出棧
        stack(top)=[];
        top=top-1;
    end    
end

A=compresstable2matrix(re);
figure;
netplot(A,1)

compresstable2matrix.m

function A=compresstable2matrix(b)
    [n ~]=size(b);
    m=max(b(:));
    A=zeros(m,m);

    for i=1:n
        A(b(i,1),b(i,2))=1;
        A(b(i,2),b(i,1))=1;
    end

end

 


免責聲明!

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



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