BFS和順序佇列求最短路徑

2021-09-29 07:02:22 字數 2598 閱讀 2502

資料結構的課程開始也有一段時間了,第一次實驗作業中,有這樣一道題:

大意是說給定兩個數軸上的點m,n.限定m的移動方式有3種:

①:左移一步:即mnew=m-1;

②:右移一步:即mnew=m+1;

③:右跳一步:即mnew=m*2;

問m最少移動幾次可以到達n;

初次看題我沒想到用哪種資料結構,自己學得慢…與老師無瓜.因為之前用棧做了字首表示式的題,還

試了乙個迷宮的題,發現它的結構很適合用回溯法,因為先進後出,只要彈出棧頂就回到上一步了。

於是我想這題可不可以按迷宮的做法來做,看上去也是尋找路徑問題,並且還簡化了許多。此時,我

還沒明白的是棧的那種搜尋其實是遞迴的,並且是dfs搜尋,它可能找到解,但未必是最優解,方向就

偏了。苦苦掙扎了一夜,死在遞迴上,多虧有人點醒,我又去翻書看佇列,不禁後悔思索題目時沒有

往後翻翻書,因為當時我已經會寫順序,迴圈,鏈式的佇列了,但還沒有看書上例題。結果一看,佇列

居然也可以用來解迷宮。了解到它是屬於bfs搜尋後,大致了解了一下bfs能求得的是最優解,對於求最

短路徑很有用的時候,我才恍然大悟。仿照例程寫出了題解:

#include

#include

#define maxsize 100

typedef

struct

box;

typedef box elementtype;

typedef

struct

queue;

queue *

createordque()

intisempty

(queue* q)

intenqueue

(queue *q,elementtype e)

}int

dequeue

(queue *q,elementtype *e)

}int

bfs(

int start,

int end)

for(di=

0;di<

3;di++

)//cxk的三種走法

if(step[cst]==0

)//尚未走過的話}}

free

(qu)

;return1;

}void

print

(queue *qu,

int front)

//因為是順序佇列,元素還在陣列裡,逆向尋找輸出

while

(k!=0)

;//順序佇列,第乙個位置在0

printf

("路徑為:\n");

while

(k//遍歷整個佇列,因為正確的路徑標記為-1

k++;}

printf

("\n總共走 %d步"

,count-1)

;}intmain()

首先我們需要乙個順序佇列,剛開始我不太明白為什麼不用迴圈佇列,就上網查bfs可不可以用迴圈佇列實現,未果。在寫的過程中我意識到,如果是迴圈佇列的話,當陣列大小maxsize不合適的話:比如為

50,但是m和n分別接近陣列兩端,此時在搜尋過程中,會覆蓋走過的路徑,最後我們是輸出不了找到的路徑的。大概是這個原因吧,希望有人批評指正。

好了,再說程式,順序佇列的資料域我們用乙個結構體box,代表位置格仔,這個格仔上有座標資訊和它從哪個格仔過來的資訊(pre),之後我們可以根據這個來輸出路徑。

接下來就是bfs的框架了:

我們用乙個step陣列來標記當前位置有沒有走過防止重複遍歷。並且這個陣列的大小應當設為step[end+1],原因是陣列預設是從0計數的,我們輸入終點為18的話,若為step【end】,則越界了。

框架:

int bfs(起點,終點)

//如果不是的話

for(di=0;di《移動方式個數;di++)

if(如果nst位置尚未走過,根據step判斷)

}//如果佇列空的情況下還沒有找到終點,說明沒有路(迷宮),因為圖已經遍歷完成了

釋放佇列記憶體

return 0;

下面用圖來分析一下

在佇列上看是怎麼樣的,其中起點s進入後,會將它能走的a,b,c三種方式的位置入隊,

起點不是終點(這裡不說起點就是終點的情況,那沒有意義了)

所以將所有可走的方式入隊,然後重複這個過程,s_1(a)的意義是起點s開始第一層(看成樹)第乙個結點

依次類推,s_1_2(a)是從s_1(a)開始的第一種走法,在第二層。

接著用樹狀圖表示一下:

現在就清晰了,為什麼bfs叫廣度優先。它每到乙個點,先把從這個點出發所有能引出的子節點入隊,然後利用佇列先進先出(先進就先檢查)的特點一層層的遍歷。這樣能最先找到的解必然是最短路徑

呼~終於描述完了,自己思路也清晰了。

有問題一定幫我指出來嗷!

BFS求最短路

假設有乙個n行m列的迷宮,每個單位要麼是空地 用1表示 要麼是障礙物 用0表示 如和找到從起點到終點的最短路徑?利用bfs搜尋,逐步計算出每個節點到起點的最短距離,以及最短路徑每個節點的前乙個節點。最終將生成一顆以起點為根的bfs樹。此時bfs可以求出任意一點到起點的距離。poj3984 bfs求最...

BFS求最短路

假設有乙個n行m列的迷宮,每個單位格要麼是空地 用1來表示 要麼是障礙物 用0來表示 如何找到從起點到終點的最短路徑?分析 要找到終點到起點的最短路徑,可以使用二叉樹的bfs,因為二叉樹的bfs的訪問順序就是結點到根節點的距離,從小到大訪問的,因此可以從迷宮圖的起點開始進行bfs的寬度優先遍歷。遍歷...

最短路 求最長最短路,求最短路的路徑

hdu 1595 find the longest of the shortest include include include include include include include include include include include include include defi...