深度優先ナビゲーション(DFS)
27496 ワード
深度優先ナビゲーション
探索グラフです.
ルートノードから次のブランチ(branch)に進む前に、ブランチを完全にナビゲートする方法.
自己呼び出しのループアルゴリズム.
時間の複雑さ
接点数:N、幹線数:E
隣接リストで表される図形O(N+E)
隣接行列で表されるパターンO(N^2)
長所
現在のパス上のノードを覚えるだけなので、リポジトリ間の需要は相対的に少ない.
ターゲットノードがより深い位置にある場合は、すばやく取得できます.
BFSよりも簡単に実現できる.
短所
単純探索はBFSより遅い.
危害がない状況では、苦境に陥る可能性がある.
深度優先ナビゲーションは、解決後に終了するため、最短パスではない可能性があります.
実施方法
全部で4種類ある
列を作る
鬼定桟で
1.隣接行列
public class DFS_Array {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 정점의 개수
int m = sc.nextInt(); // 간선의 개수
int v = sc.nextInt(); // 탐색을 시작할 정점의 번호
boolean visited[] = new boolean[n + 1]; // 방문 여부를 검사할 배열
int[][] adjArray = new int[n+1][n+1];
// 두 정점 사이에 여러 개의 간선이 있을 수 있다.
// 입력으로 주어지는 간선은 양방향이다.
for(int i = 0; i < m; i++) {
int v1 = sc.nextInt();
int v2 = sc.nextInt();
adjArray[v1][v2] = 1;
adjArray[v2][v1] = 1;
}
System.out.println("DFS - 인접행렬 / 재귀로 구현");
dfs_array_recursion(v, adjArray, visited);
Arrays.fill(visited, false); // 스택 DFS를 위해 visited 배열 초기화
System.out.println("\n\nDFS - 인접행렬 / 스택으로 구현");
dfs_array_stack(v, adjArray, visited, true);
}
//DFS - 인접행렬 / 재귀로 구현
public static void dfs_array_recursion(int v, int[][] adjArray, boolean[] visited) {
int l = adjArray.length-1;
visited[v] = true;
System.out.print(v + " ");
for(int i = 1; i <= l; i++) {
if(adjArray[v][i] == 1 && !visited[i]) {
dfs_array_recursion(i, adjArray, visited);
}
}
}
//DFS - 인접행렬 / 스택으로 구현
public static void dfs_array_stack(int v, int[][] adjArray, boolean[] visited, boolean flag) {
int l = adjArray.length-1;
Stack<Integer> stack = new Stack<Integer>();
stack.push(v);
visited[v] = true;
System.out.print(v + " ");
while(!stack.isEmpty()) {
int w = stack.peek();
flag = false;
for(int i = 1; i <= l; i++) {
if(adjArray[w][i] == 1 && !visited[i]) {
stack.push(i);
System.out.print(i + " ");
visited[i] = true;
flag = true;
break;
}
}
if(!flag) {
stack.pop();
}
}
}
}
public class DFS_List {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 정점의 개수
int m = sc.nextInt(); // 간선의 개수
int v = sc.nextInt(); // 탐색을 시작할 정점의 번호
boolean visited[] = new boolean[n + 1]; // 방문 여부를 검사할 배열
LinkedList<Integer>[] adjList = new LinkedList[n + 1];
for (int i = 0; i <= n; i++) {
adjList[i] = new LinkedList<Integer>();
}
// 두 정점 사이에 여러 개의 간선이 있을 수 있다.
// 입력으로 주어지는 간선은 양방향이다.
for (int i = 0; i < m; i++) {
int v1 = sc.nextInt();
int v2 = sc.nextInt();
adjList[v1].add(v2);
adjList[v2].add(v1);
}
for (int i = 1; i <= n; i++) { // 방문 순서를 위해 오름차순 정렬
Collections.sort(adjList[i]);
}
System.out.println("DFS - 인접리스트");
dfs_list(v, adjList, visited);
}
// DFS - 인접리스트 - 재귀로 구현
public static void dfs_list(int v, LinkedList<Integer>[] adjList, boolean[] visited) {
visited[v] = true; // 정점 방문 표시
System.out.print(v + " "); // 정점 출력
Iterator<Integer> iter = adjList[v].listIterator(); // 정점 인접리스트 순회
while (iter.hasNext()) {
int w = iter.next();
if (!visited[w]) // 방문하지 않은 정점이라면
dfs_list(w, adjList, visited); // 다시 DFS
}
}
}
Reference
この問題について(深度優先ナビゲーション(DFS)), 我々は、より多くの情報をここで見つけました https://velog.io/@away0419/깊이-우선-탐색DFSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol