DFSとBFS
18677 ワード
DFS、BFSとは?
DFSとBFSはグラフィックをブラウズする方法です.
言葉だけで説明するのは難しい概念なので、絵を見て何がいいのかを見つけるのがいいです.
画像ソースリンク
DFS-深度優先ナビゲーション
迷宮では、死の道が現れるまで片側の壁に沿って深くナビゲートします.
死胡に遭遇すると同時に、最寄りの分かれ道に戻り、別の方向に沿って袋小路までまっすぐ行く方法.
BFS-幅優先ナビゲーション
まず迷宮の起点に近い点をナビゲートする方法.
DFS、BFS応用
バックアップ・ページのDFSとBFSに問題があります.
DFSとBFS
JSを使ってこの問題を解決しましょう.
無限ループを防止するには、DFSとBFSがノードにアクセスしているかどうかを確認する必要があります.
あらかじめ準備する
function solution(N, M, V, MArray) {
let answer = [];
return answer;
}
const N = 4; //정점의 개수
const M = 5; //간선의 개수
const V = 1; //시작할 정점의 번호
const MArray = [
[1, 2],
[1, 3],
[1, 4],
[2, 4],
[3, 4],
]; //간선이 연결하는 두 정점의 번호
console.log(solution(N, M, V, MArray));
このように見ると難しいと思います図に示すように、このような構造の図形です. let isVisit = new Array(N + 1).fill(false); //[ false, false, false, false, false ]
配列の個数をN+1とするのは,ノードが1から,配列のインデックスが0から始まるためである.この違いによる混乱を避けるために,アレイの大きさを1増やした.したがって、isVisit[0]
は使用されない.isVisit[1]
です.isVisit[2] = true
隣接リストの説明は、下のリンクで詳しく説明されています.を参照してください.
隣接リストリファレンス
function adjacency(N, MArray) {
let arr = Array.from(new Array(N + 1), () => []); //[[],[],[],[],[]]
for (let item of MArray) {
arr[item[0]].push(item[1]);
arr[item[1]].push(item[0]);
}
return arr;
}
function solution(N, M, V, MArray) {
......
//인접리스트
const adjacencyList = adjacency(N, MArray); //[ [], [ 2, 3, 4 ], [ 1, 4 ], [ 1, 4 ], [ 1, 2, 3 ] ]
隣接するリストを作成する関数は、個別に作成されます.ノード数+1より大きい配列を作成し、空の配列で配列を埋めます.+1の理由は、アクセスチェックの理由と同じです.
[[],[],[],[],[]]
したがって、アレイ内の要素を1つずつ取り出す場合は、双方向のグラフィックであることを考慮します.
arr[1]
の空の配列に2を追加し、arr[2]
の空の配列に1を追加する.=>
[[],[2],[1],[],[]]
[ [], [ 2, 3, 4 ], [ 1, 4 ], [ 1, 4 ], [ 1, 2, 3 ] ]
のような隣接リストが完了する.[ 2, 3, 4 ]
は、ノード1(index 1)が2、3、および4番ノードに接続されていることを示す.DFS-深度優先ナビゲーション
DFSは再帰関数を用いて問題を解決する.
const startNode = V;
const DFS = (curNode) => {
isVisit[curNode] = true;
answer.push(curNode);
for (let subNode of adjacencyList[curNode]) {
if (isVisit[subNode]) continue;
DFS(subNode);
}
};
DFS(startNode);
ゆっくり解きほぐそう1.最初のDFSは
startNode
人1を含む.2.1番ノードにアクセスしているかどうかを確認します.
isVisit[1] = true
isVisit === [ false, true, false, false, false ]
3.どのような手順でナビゲーションを行うかを知るために、answer.push(1)
を実行します.answer ===
[1]
4.隣接リストのインデックス1に対応する配列([2,3,4]
)から要素(サブノード)を1つずつ取り出す.5.ノードが取り出されたかどうかを確認します(現在は2).
if (isVisit[2]) continue
ノードが再帰関数も難点であるため,DFS(2)について議論する.
1.2番目のノードにアクセスしたかどうかを確認します.
isVisit[2] = true
isVisit === [ false, true, true, false, false ]
2.どのような手順でナビゲーションを行うかを知るために、answer.push(2)
を実行します.answer ===
[1,2]
4.隣接リストのインデックス2に対応する配列([1,4]
)から要素(サブノード)を1つずつ取り出す.5.取り出したノード(現在は1)がアクセスしたノードであるかどうかを確認します.
if (isVisit[1]) continue
6.1はアクセスしたノードです.したがって、次のノードを確認します.if (isVisit[4]) continue
7.7は未アクセスのノードなので、4をDFSに入れてDFS関数を再実行します.これにより、すべてのノードがアクセス登録を完了すると、最終的な答えは
[1,2,4,3]
を含む.BFS-幅優先ナビゲーション
BFSはキューを使用して問題を解決する.
const startNode = V;
const BFS = (curNode) => {
isVisit[curNode] = true;
answer.push(curNode);
let queue = [curNode];
while (queue.length > 0) {
for (let subNode of adjacencyList[queue.shift()]) {
if (isVisit[subNode]) continue;
queue.push(subNode);
isVisit[subNode] = true;
answer.push(subNode);
}
}
};
BFS(startNode);
}
ゆっくり解きほぐそう1.最初のDFSは
startNode
人1を含む.2.1番ノードにアクセスしているかどうかを確認します.
isVisit[1] = true
isVisit === [ false, true, false, false, false ]
3.どのような手順で探索したかを知るために回答してください.push(1)を行います.answer ===
[1]
4.queueという配列を作成し、1を挿入します.let queue = [1]
5.キューに要素がないまでwhile文を作成します.while (queue.length > 0)
ここから繰り返します.5-1.
adjacencyList[빼낸 요소 1]
の配列([2,3,4]
)から1つの要素がキューの最初の要素として1つずつ取り出される.queueの最初の要素1が削除されたため、現在のqueueは空です.
5-2. ノード(現在2)がアクセスされているかどうかを確認します.
if (isVisit[2]) continue
アクセスしたノードの場合は、次の要素を確認します.アクセスしていないノードの場合
5-3. ノードをqueueに追加します.止まらないように
queue.push(2)
queue === [2]
5-4. 2ノードにアクセスしているかどうかを確認します.isVisit[2] = true
isVisit === [ false, true, true, false, false ]
5-5. どのような手順でナビゲーションを行うかを知るために、answer.push(2)
を行います.answer ===
[1,2]
これにより、すべてのノードがアクセス登録を完了すると、最終的な答えは[1,2,3,4]
を含む.現在の問題では、1番ノードが2、3、4に接続されているため、queueは正しく使用されていません.
例えば、このような構造であれば
1->2->3の順序でナビゲートすると、for文は終了し、キューには
[2,3]
が含まれます.queueに要素があるため、while文は再び要素を繰り返します.
for (let subNode of adjacencyList[queue.shift()])
は、2をキューに入れ、2のサブノード4を発見する.このようにして問題を解決する.Reference
この問題について(DFSとBFS), 我々は、より多くの情報をここで見つけました https://velog.io/@yooss2006/DFSBFSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol