深さ優先探索
深さ優先探索とは
深さ優先探索(DFS : Depth First Search)とはグラフや木構造を探索するためのアルゴリズムであり、探索を開始する位置から近いものから探索していく探索手法。
アルゴリズム
流れ
次 の図のような木構造があったとする。
頂点1
を始点として、幅優先探索を行うと次のような流れになる。
- 始点は探索済みとして記録する。
頂点1
と繋がっている頂点2,4
を次の探索点に追加する。
-
頂点
4
探索済みとして記録する。 頂点4
と繋がっている頂点7,6
を次の探索点に追加する -
頂点
6
探索済みとして記録する。 頂点6
と繋がっている頂点8
を次の探索点に追加する -
頂点
8
探索済みとして記録する。 頂点8
と繋がっている頂点は存在しないので何も追加しない -
頂点
7
探索済みとして記録する。 頂点7
と繋がっている頂点は存在しないので何も追加しない -
頂点
2
探索済みとして記録する。 頂点2
と繋がっている頂点3
を次の探索点に追加する -
頂点
3
探索済みとして記録する。 頂点3
と繋がっている頂点5
を次の探索点に追加する -
頂点
5
探索済みとして記録する。 頂点5
と繋がっている頂点は存在しないので何も追加しない
使用するデータ構造
流れの次の探索点の配列の順番を見ると配列新たに要素を追加する際も配列から要素を取り出す際も一番右側、要素番号の一番後ろの要素に処理を行っている。
つまり、FILO の動作が行われている。この FILO を表すのに適したデータ構造が**Stack**である。
- 次の探索点 の配列の一番後ろの要素を取り出し、探索を行う
- 探索した際に新たな未探索要素が見つかったら、次の探索点の配列の後ろに要素の追加する
以上の 2 つの処理を行えれば深さ優先探索を行うことができる。 そのため、それぞれ Stack を用いると
- 次の探索点の配列の一番後ろの要素を
pop
し(取り出し)、探索を行う - 探索した際に新たな未探索要素が見つかったら、次の探索点の配列の後ろに
push
(要素の追加)する
と言えるので Stack を用いてることができることがわかる。
走査順
深さ優先探索には 3 種類の走査順が存在する。走査順とは簡単にいうとどのタイミングで訪れたことを記録するかということである。 探索する順番は同じであり(根から木構造の左に沿う形)、訪れた番号の記録順が異なる。
- 行きがけ順(頂点に到達時)
- 通りがけ順(左部分木を走査終了時)
- 帰りがけ順(部分木を走査終了時)
それぞれの走査順序は次のようになる。(上の流れの記録(探索済み点の並び)は行きがけ順である)
それぞれの走査順の違いを次の図をベースに確認する。赤点線に沿って頂点を訪れるとする。
記録する順番は頂点についてる青色の丸を通ったタイミングで頂点を記録する。
行きがけ順
頂点に訪れたタイミングで探索済みとする走査順
1 → 3 → 6 → 5 → 7 → 2 → 4
の順に記録される。
通りがけ順
左部分木を走査し終えたタイミングで探索済みとする走査順(多分木では定義されていない)
6 → 3 → 7 → 5 → 1 → 2 → 4
の順に記録される。
帰りがけ順
全ての子ノードを訪れたタイミングで探索済みとする走査順
6 → 7 → 5 → 3 → 4 → 2 → 1
の順に記録される。