廣度優先搜尋演算法

2021-06-04 04:51:02 字數 2185 閱讀 8488

廣度優先搜尋(bfs)

這個是第乙個研究的課題,廣度優先搜尋也叫寬度優先搜尋,英文為breadth first searth,開始看的時候一頭霧水,基本也能懂大致意思,但是還不是真正的理解,今天又仔細看看,大致理解上又更深了一層吧。

下面來總結下,自己的一些體會,以及對它的獨到的理解。

大的方面來說它是一種按照層次類似樹的形式,按層次遍歷的過程。

假設從某乙個頂點v出發,訪問v之後,(訪問可理解為,達到了該點,並且函式可以並且已經呼叫了),然後找出v的所有鄰接點,依次訪問,如果v的鄰接點有(v1,v2)的話,那麼下一步在接著從v1,和v2出發訪問v1的鄰接點,v2的鄰接點,然後知道圖中所有的點都被訪問完為止。

上面是大致思路,進一步思考,在訪問v1的鄰接點的時候,必然會找到它的前繼就是上乙個給它傳送的那個點,此處是v,就會發生重複了,也就是說,在找後面的鄰接點的時候,我們最好要保證那些已經訪問過的點,這時候不再訪問了,否則就是死迴圈了,這裡就要要求我們有個標誌去記錄那些已經訪問過的點,讓他們跟那些未訪問的不一樣。

前面提到那個層次性,就是首先訪問跟v為第一步的點,然後第一步的點,鄰接點,也就是v的第二層點,那麼我們怎麼才能體現出這個層次性呢?

最笨的方法是,可以建立多個陣列,一步乙個陣列,第一步的為陣列名為1,第二步為陣列2,第三步的為陣列3,。。。。。依次建立,這樣對於小型的圖還可以但是大型的圖就浪費空間很大,這樣還很不靈活,陣列都是固定的,對於每乙個點,它的鄰接點並不是固定的,所以我們想到要用動態陣列,並且這個動態陣列可以為每一步服務,而不必每次都要建立乙個新的陣列。

動態陣列中首先想到用棧來實現,先把v放進去,第一層,然後以v為起點開始找它的鄰接點v1,v2,把v1,v2入棧,然後在找v1,v2的鄰接點的時候就會發現,當找到v1的鄰接點之後,我們把v1先出棧,然後把它的鄰接點入棧,這時候,v2就會被退到棧尾,那麼下一次出棧的就是v1的鄰接點而不是v2體現不出層次性了。

由上面的分析,發現棧在這裡不合適,那麼我們選用佇列來實現,因為每次進來的點都排在隊頭,然後他們依次離開隊的時候都把他們的鄰接點全部入隊,都在隊尾,不會影響,隊頭上一層的那些點,然後依次類推下去,上一層的鄰接點全部出佇列之後,就剩下的都是上一層佇列那些點所有的鄰接點了。

下面我們用文字把大致的過程思路給理一下

1.找到乙個標誌把所有點都表示下,未訪問的,和訪問過的要區別開來。

2,隨機找到乙個點,從當前點開始,放到佇列的隊頭。

3,找到隊頭的元素,刪去,並且找到該點所有的鄰接點,把那些沒有訪問過的點放到隊尾去。

4,當最後佇列空的時候就把所有點遍歷完了。

然後我們用c語言來表示一下。

對於標誌我們用陣列visit來表示,該陣列儲存了所有點,下標代表該點,元素值為true,表示訪問過,反之,表示未訪問過。

/*enqueue 入佇列

g.vexnum    圖的頂點數目

dequeue(q,u)   刪除隊頭元素並賦值為u

queueempty(q) 判斷隊頭元素是否為空

firstadjvex(g,u) u的第乙個鄰接點

nextadjvex(g,u,w)

u的除了w之外的鄰接點,如果沒有,則返回-1*/

for(i=0;i

visit[i]=false;//首先所有點都初始化為未訪問過 

visit[0]=true;//此處假定是從第乙個點開始訪問,就把該點值變為true 

enqueue(q);//然後該點就入佇列 

while(!queueempty(q)) }

}如果你用的是嚴蔚敏版的c語言資料結構書的話,就會發現其實這裡的演算法,跟課本上還不太一樣,少了開頭的乙個對所有點的乙個大迴圈,事實上,這個大迴圈的作用是使該演算法更全面能處理非連通圖,因為對於連通圖來說,從某乙個點出發按層次結構必然會將所有點訪問完的,除非該點與那個「某一點」出發的搜尋圖本來就不連通,所以上面的演算法只是使用於連通圖,非連通圖要加上乙個對所有點進行一次遍歷的排查,發現如果有點還未訪問,那麼就從該點開始進行上面的演算法,把以該點為起始點的點都遍歷完。

這樣一步一步的寫出這樣的過程,思考為什麼要這麼做,能讓我更清晰知道發明該演算法的人的思考過程,只有這樣才能更深刻的理解該演算法,不然,我們都只是停留在,嗯,是這樣,就是弄個佇列嘛,儲存下,然後就好了,就是外面加個大迴圈嘛,為什麼呢?

經過仔細的分析,一步一步的推導,從本文也許可以找到答案。

因為今天去調查了班級裡一些還算相當不錯的同學,其實他們對這個都是支支吾吾的不是特別的明白,故認真的總結本文,來加深自己的對廣度優先搜尋演算法理解。

廣度優先搜尋演算法

在深度優先搜尋中,深度越大的結點越先得到擴充套件。如果把它改為深度越小的結點越先得到擴充套件,就是廣度優先搜尋法。廣度優先搜尋演算法的基本思想 1 建立乙個空的狀態佇列ss 2 建立乙個空的狀態庫sb 3 把初始狀態s 0 存入佇列ss中 4 若佇列狀態是目標狀態,則搜尋成功,演算法執行中止。如該狀...

廣度優先搜尋演算法

看了下廣度優先搜尋演算法得定義為從乙個頂點開始,找到最短路勁,歸結為一種連通圖得遍歷策略 如果我們要求v0到v6的一條最短路 假設走乙個節點按一步來算 注意 此處你可以選擇不看這段文字直接看圖3 1 我們明顯看出這條路徑就是v0 v2 v6,而不是v0 v3 v5 v6。先想想你自己剛剛是怎麼找到這...

廣度優先搜尋演算法

廣度優先搜尋解決兩個問題 第一類問題 從節點a出發,有前往節點b的路徑嗎?第二類問題 從節點a出發,前往節點b的哪條路徑最短?假設你經營著乙個芒果農場,需要尋找芒果銷售商,以便將芒果賣給他。在facebook,你與芒果銷售商有聯絡嗎?為此,你可在朋友中查詢。這樣一來,你不僅在朋友中查詢,還在朋友的朋...