深度優先遍歷
廣度優先遍歷是圖的一種遍歷方式, 它的思想就是遍歷這個點相鄰的所有的點, 再對這些點進行廣度優先遍歷. 如下圖所示
首先我們從a點開始遍歷, 然後遍歷所有和a相鄰的點f和點g:
然後對f和點g進行遍歷進行遍歷, 得到點e, h, k和b:
然後再繼續, 知道所有的點都遍歷完成:
首先, 我們先定義圖graph類:
/**
* 無向圖
*/public
class
graph
}public
intgetv()
public
intgete()
/** * 新增邊
** @param v
* @param w
*/public
void
addedge
(int v,
int w)
public iterable
adj(int v)
}
接著編寫bfs**, 這裡我們用乙個陣列marked來標記點是否被訪問過, 這樣我們就不需要再一次對這個點進行訪問了. 同時, 我們用乙個佇列來儲存我們遍歷的節點, 每次我們都從佇列中取出節點然後訪問, 將新遍歷的節點加入到佇列中, 當佇列中不在有節點是bfs就結束了:
* 廣度優先遍歷
*/public
class
breadthfirstpaths
private
void
bfs(graph g,
int s)}}
}/**
* 判斷s和v是否相連線
** @param w
* @return
*/public
boolean
haspathto
(int w)
/** * 獲取起點s到頂點v的路徑
** @param v
* @return
*/public iterable
pathto
(int v)
list
path =
newarraylist
<
>()
;for
(int i = v; i != s; i = edgeto[i]
) path.
add(s)
;return path;
}}深度優先遍歷和廣度優先不同, 它的思想是每一次值找乙個點, 一條路走到底, 然後在返回去遍歷第二個點, 這類似於我們走迷宮一直走下去, 知道走到絕路再退回上乙個路口走嚇一跳道
我們同樣以點a作為起點, 首先我們選擇一條路走到底:
走到絕路了, 退回到點e, 換一條路走:
然後再繼續回退, 知道所有的點都遍歷完:
我們沿用剛剛定義的graph類. 我們不難發現, dfs很容易用遞迴來實現:
*
** 深度優先遍歷 */
public
class
depthfirstsearch
private
void
dfs(graph g,
int v)}}
/** * 判斷s和v是否相連線
** @param w
* @return
*/public
boolean
haspathto
(int w)
/** * 返回和s相連線的頂點數目
** @return
*/public
intgetcount()
/** * 獲取起點s到頂點v的路徑
** @param v
* @return
*/public iterable
pathto
(int v)
list
path =
newarraylist
<
>()
;for
(int i = v; i != s; i = edgeto[i]
) path.
add(s)
;return path;
}}
當然, 我們同樣的可以用棧來實現dfs, 將訪問的節點入棧, 訪問完就出棧, 這樣也可以做到dfs:
private
void
dfsbystack
(graph g,
int v)}if
(w != u)
else
}}
深度優先遍歷 和 廣度優先遍歷
圖的廣度優先搜尋是樹的按層次遍歷的推廣,它的基本思想是 首先訪問初始點vi,並將其標記為已訪問過,接著訪問vi的所有未被訪問過的鄰接點 vi1,vi2,vi t,並均標記已訪問過,然後再按照vi1,vi2,vi t的次序,訪問每乙個頂點的所有未被訪問過的鄰接點,並均標記為已訪問過,依次類推,直到圖中...
廣度優先遍歷和深度優先遍歷
1.1 概念 以初始節點v0作為第一層節點,接著訪問它。然後迭代第一層節點即v0,訪問它相鄰接的沒有訪問過的節點比如v1,v2,v1,v2加入到第二層節點 迭代第二層節點v1,v2,v1,v2依次訪問相鄰接的沒有訪問過的節點,重複上述步驟直至所有節點都被訪問過為止。如圖所示首先訪問根節點v0,並將v...
深度優先遍歷和廣度優先遍歷
其實簡單來說 深度優先就是自上而下的遍歷搜尋 廣度優先則是逐層遍歷 對於演算法來說 無非就是時間換空間 空間換時間 深度優先不需要記住所有的節點,所以占用空間小,而廣度優先需要先記錄所有的節點占用空間大 深度優先有回溯的操作 沒有路走了需要回頭 所以相對而言時間會長一點 深度優先採用的是堆疊的形式,...