이 장의 내용은 Java, Github 코드 웨어하우스에서 구현됩니다: https://github.com/ZhekaiLi/Code/tree/main/Graph/src
기사의 사진을 보려면 과학적인 인터넷 액세스가 필요할 수 있습니다!사진 관리는 github를 이용하기 때문에 로딩이 안되는 상황이 발생하면 담벼락을 뒤집어주세요
[참고] imooc Mr. Bobo: Fun Algorithm Series - 인터뷰 및 프로모션을 위한 그래프 이론 필수(Java Edition)
[이전 블로그 링크]
그래프 이론 알고리즘(1, 2): 그래프의 분류, 그래프의 기본 개념(무향 그래프 및 유향 그래프, 비가중 그래프, 비순환 그래프, 완전한 그래프, 이분 그래프, 단순 그래프, 연결된 그래프 구성 요소, 스패닝 그래프 트리, 하위 그래프 및 상위 그래프)
그래프 이론 알고리즘(3): 그래프의 기본 표현(인접 행렬, 인접 목록, 인접 행렬 및 인접 목록 비교)
그래프 이론 알고리즘(4): 그래프의 깊이 우선 Traversal DFS
그래프 이론 알고리즘 (5): 그래프 너비 우선 순회 BFS
그래프 이론 알고리즘 (6): LeetCode 그래프 이론 알고리즘 연습 (785. 이분 그래프의 판단, 695. 섬의 최대 면적, Floodfill 알고리즘, Union Check)
5. 그래프 BFS의 너비 우선 탐색
트리의 너비 우선 탐색을 먼저 살펴보자 다음 그림은 트리의 BFS를 수행하기 위해 큐를 사용하는 일반적인 프로세스를 보여줍니다.
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-19_13-30-49.gif)
bfs(root); // 从根结点开始遍历
bfs(TreeNode node)
queue.add(node);
while(!queue.isEmpty)
v = queue.remove();
list.add(v);
for(w: v.son())
queue.add(w)
그래프 의 너비 우선 탐색 은 노드 w가 방문되었는지 여부에 대한 판단이 queue.add(w)
전에 . 시간 복잡도도 O( V + E ) O(V+E)오 ( V+마 )
자바 구현: GraphBFS.java
DFS가 해결할 수 있는 대부분의 문제는 BFS로도 해결할 수 있습니다.
5.1 예: 두 점 사이의 경로 찾기
마찬가지로 섹션 4.2
pre[0...V-1] = -1;
s = 0; // 自定义的起始点
t = 5; // 自定义的终止点
bfs(s); // 从根结点开始遍历
bfs(int v)
queue.add(v);
pre[v] = v;
while(!queue.isEmpty)
v = queue.pop();
list.add(v);
for(w: v.son())
queue.add(w);
pre[w] = v;
자바 구현: SingleSourcePathBFS.java
5.2 속성: 비가중 그래프 최단 경로
0 → 6 0\to6도 마찬가지 입니다 .0→6. BFS의 경로는 DFS의 경로보다 짧습니다.이 속성은 모든 지점에도 적용됩니다. 즉,BFS는 모든 지점과 루트 노드 사이의 최단 경로를 찾을 수 있습니다.
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-20_10-48-56.jpg)
이는 BFS가 루트 노드에서 시작하여 근거리에서 원거리로 순회하는 layer-order traversal 이기 때문이며 , 각 순회는 가장 가까운 노드를 찾기 때문입니다. = 가장 우수함)
순회 과정에서 거리 정보를 직접 기록 dis[]
하면 루트 노드에서 임의의 노드까지의 최단 거리를 직접 읽어낼 수 있다.
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-20_11-06-35.jpg)
자바 구현: USSSPath.java
5.3 비교: DFS와 BFS
BFS와 DFS(비재귀적)를 비교할 때 유일한 차이점은 DFS는 스택을 사용하고 BFS는 대기열을 사용한다는 것입니다(노드를 처리할 때 DFS 헤드 인 및 헤드 아웃, BFS 테일 인 및 헤드 아웃) ( statck.add(s)
해당 stack.push()
, statck.remove()
해당 stack.pop()
)
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-20_11-26-00.jpg)
또한 위의 그림 stack/ queue
을 대체하기 위해 임의의 구조를 사용 하여 사용자 정의 순회 방법을 달성할 수도 있습니다.
예를 들어 임의의 컨테이너(무작위 대기열)를 사용하여 가장자리에 무작위로 액세스하여 무작위 미로를 생성할 수 있습니다.
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-20_11-36-38.jpg)
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/Snipaste_2021-07-20_11-36-54.jpg)
더 크고 보기 좋은 예:
![](https://github.com/ZhekaiLi/PICTURE-for-markdown/raw/master/2021-07/GIF%202021-7-20%2011-40-27.gif)