資料結構的課程開始也有一段時間了,第一次實驗作業中,有這樣一道題:
大意是說給定兩個數軸上的點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...