深度與廣度 總結
1.深度優先搜尋(回溯法)
[演算法思路]
[演算法描述]
void dfs(int step)
返回}
[演算法效率]
深度優先搜尋從最開始的狀態出發,遍歷所有可以到達的狀態.由此可以對所有的狀態進行操作,或列舉出所有的狀態.作為搜尋演算法的一種,dfs對於尋找乙個解的np(包
括npc)問題作用很大.
但是,搜尋演算法畢竟是時間複雜度是
o(n!)
的階乘級演算法,它的效率比較低,在資料規模變大時,這種演算法就顯得力不從心了.
關於深度優先搜尋的效率問題,有多種解決方法.最具有通用性的是剪枝(prunning),也就是去除沒有用的搜尋分支.
有可行性剪枝和最優性剪枝兩種.此外,對於很多問題,可以把搜尋與動態規劃(dp,dynamic programming)、完備匹配(匈牙利演算法)等高效演算法結合.
2.寬度優先搜尋(分支限界法)
[演算法思路]
寬度優先搜尋(bfs,breadth-first search)也是搜尋的手段之一.他與深度優先搜尋類似,
從某個狀態出發搜尋所有可以到達的狀態.
根據寬度優先搜尋的特點,採用佇列實現比較簡單.
[演算法描述]
/*遍歷連通圖*/
void bfs(graph g,int v)
{
/*按廣度優先非遞迴遍歷連通圖g*/
cout<=0;w=nextadjvex(g,u,w))
{ /*依次檢查u的所有鄰接點w,firstadjvex(g,u)表示u的第乙個鄰接點*/
/*nextadjvex(g,u,w)表示u相對於w的下乙個鄰接點,w>=0表示存在鄰接點*/
if(!vistited[w]) /*w為u的尚未訪問的鄰接頂點*/
{cout<[演算法效率]
與深度優先不同之處在與搜尋的順序,寬度優先搜尋總是先搜尋距離初始狀態近的狀態.
也就是說,它是按照開始狀態->只需1次轉移就可以到達的所有狀態->只需2次轉移
就可以到達
的所有狀態->.....這樣的順序進行搜尋.對於同乙個狀態,寬度優先搜尋只經過一次,因此複雜度為
o(狀態數*轉移的方式).很容易地用來求最短路徑、最少操作之類問題的答案.
廣度搜尋的判斷重複如果直接判斷十分耗時,我們一般借助雜湊表來優化時間複雜度.
3.death-breadth總結
寬度優先搜尋與深度優先搜尋一樣,都會生成所有能夠遍歷到的狀態,因此需要對所有狀態進行
處理時使用寬度優先也是可以的.但是遞迴函式可以很簡短地編寫,而且狀
態的管理也更簡單,所以大
多數情況下還是用深度優先搜尋實現.反之,在求取最短路時深度優先搜尋需要反覆經過同樣的狀態
,所以還是使用寬度優先搜尋比較好.
寬度優先搜尋會把狀態逐個加入佇列,因此通常需要與狀態數成正比的記憶體空間.反之,深度優先搜尋是與
最大的遞迴深度成正比的.一般與狀態數相比,遞迴的深度並不會
太大,所以可以認為深度優先搜尋更加
節省記憶體.
深度與廣度
首先宣告,這裡不是說的圖的深度優先遍歷和廣度優先遍歷,而是心情隨筆,哈哈。計算機技術的各個領域,都有他存在的必要,所謂存在即合理。而我又是乙個比較 花心 的人,看到什麼技術挺好玩,總要去摸一摸,耍一耍。剛開始看到有人寫了個程式,把乙個複雜的計算瞬間算出來了,好玩,看到有人做出了漂亮的介面,酷,看到有...
遍歷 廣度優先與深度優先
第一步,建立佇列,元素操作規則為 佇列尾部加入元素,頭部移除元素 第二步,把資料夾加入該佇列 第三步,從該佇列頭移除資料夾,同時依次遍歷它的所有孩子,如果孩子是檔案,則提取 如果孩子是資料夾,則加入佇列尾部 第四步,重複第三步 直到隊列為空為止。到此資料夾中所有檔案都被獲取 獲取資料夾下所有檔案 p...
深度優先dfs與廣度bfs優先搜尋總結 例題
深度優先遍歷 dfs 是對乙個連通圖進行遍歷的演算法。它的思想是從乙個頂點開始,沿著一條路一直走到底,如果發現不能到達目標解,那就返回到上乙個節點,然後從另一條路開始走到底,這種盡量往深處走的概念即是深度優先的概念。簡而言之 不撞南牆不回頭 模板如下 void dfs int t t代表目前dfs的...