The content of this chapter is implemented in java, Github code warehouse: https://github.com/ZhekaiLi/Code/tree/main/Graph/src
Viewing the pictures in the article may require scientific Internet access!Because github is used to manage pictures, if there is a situation that cannot be loaded, please turn over the wall
[Reference] imooc Mr. Bobo: Fun Algorithm Series - Graph Theory Essentials for Interview and Promotion (Java Edition)
[Links to previous blogs]
Graph Theory Algorithms (1, 2): Classification of Graphs, Basic Concepts of Graphs (Undirected Graphs and Directed Graphs, Unweighted Graphs, Acyclic Graphs, Complete Graphs, Bipartite Graphs; Simple Graphs, Connected Graphs Components, spanning tree of graphs, subgraphs and parent graphs)
graph theory algorithm (3): basic representation of graphs (adjacency matrix, adjacency list, comparison of adjacency matrix and adjacency list)
graph theory algorithm (4): depth first of graphs Traversal DFS
Graph Theory Algorithm (5): Graph Breadth First Traversal BFS
Graph Theory Algorithm (6): LeetCode Graph Theory Algorithm Exercise (785. Judgment of Bipartite Graph, 695. Maximum Area of Island, Floodfill Algorithm, Union Check)
4 Depth-first traversal of DFS for graphs
(About the front, middle, back, and layer order traversal of the tree, there is a blog that summarizes it very well: https://blog.csdn.net/zl6481033/article/details/81009388 )
Let's first look at the depth-first traversal of the tree (previously In-order traversal as an example)
preorder(root); // 从根结点开始遍历
preorder(TreeNode node)
if(node != null)
list.add(node.val);
preorder(node.left);
preorder(node.right);
Depth-first-order traversal of graphs : slightly different from trees, graph algorithms need to determine whether a node has been visited before recursion, and its time complexity is O ( V + E ) O(V+E)O ( V+E)
visited[0...V-1] = false;
// 使用 for 循环保证遍历每个点,使得算法可以应对非联通图
for(int v = 0; v < V; v++)
if(!visited[v])
dfs(v);
dfs(int v)
visited[v] = true; // 标记为已访问
list.add(v);
for(int w: adj(v))
if(!visited[w])
dfs(w);
java implementation: GraphDFS.java
4.1 Ex: Find the connected component
That is, the solution contains several connected graphs
visited[0...V-1] = -1;
ccount = 0; // 联通分量
for(v = 0; v < V; v++)
if(visited[v] == -1)
dfs(v, ccount);
ccount++;
dfs(v, ccid)
visited[v] = ccid;
list.add(v);
for(int w: adj(v))
if(visited[w] == -1)
dfs(w, ccid);
java implementation: CC.java
Find whether two points are reachable : only need to judge as follows
visited[v] == visited[w];
4.2 Ex: Find the path between two points
(not necessarily the shortest)
// pre[i] = j 表示存在路径 j->i
// pre[i] = -1 表示尚未访问,代替 visited[i] = false
pre[0...V-1] = -1;
s = 0; // 自定义的起始点
t = 5; // 自定义的终止点
pre[s] = s; // 将源头的源头设为自己
dfs(s);
// 返回值表示是否达到了目标点 t
boolean dfs(int v)
for(int w: adj(v))
if(visited[w] == -1)
pre[w] = v;
if(w == t) return true;
if(dfs(w)) return true;
return false;
==java implementation: Path.java==
4.3 Ex: Ring Detection
java implementation: CycleDetection.java
4.4 Ex: Bipartite Graph Detection
The two graphs on the left and right that look completely different are actually the same, but the form on the left is obviously a bipartite graph, while the more common and random form on the right cannot be judged intuitively.
Use DFS for bipartite graph detection:
// -1: 未访问
// 0: 二分图的一侧
// 1: 二分图的另一侧
color[0...V-1] = -1;
color[0] = 0;
dfs(0);
// 返回值表示是否检测到了目标图不是二分图的证据
boolean dfs(int v)
for(int w: adj(v))
if(color[w] == -1)
color[w] = 1 - color[v]
if(dfs(w)) return true;
else if(color[w] == color[v])
return true
return false;
java implementation: BipartitionDetection.java