Skip to content

Commit c1aa792

Browse files
committed
[Function add]
1.Add DFS way to find cycle int the graph. 2. Add conclusion.
1 parent 4a80c91 commit c1aa792

File tree

4 files changed

+198
-2
lines changed

4 files changed

+198
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileNotFoundException;
6+
import java.util.Stack;
7+
8+
public class DirectedCycle {
9+
private final boolean[] marked;
10+
private final int[] edgeTo;
11+
private Stack<Integer> cycle = null; //有向环上的所有顶点
12+
private final boolean[] onStack; //递归调用的栈上的所有顶点
13+
public DirectedCycle(Digraph g){
14+
onStack = new boolean[g.V()];
15+
marked = new boolean[g.V()];
16+
edgeTo = new int[g.V()];
17+
int size = g.V();
18+
for(int v = 0; v < size; v++)
19+
if(!marked[v]) dfs(g, v);
20+
}
21+
private void dfs(Digraph g, int v){
22+
//在此次的遍历中,记录当前的位置可能在环上。如果结束了没有在环上则改回false
23+
onStack[v] = true;
24+
marked[v] = true;
25+
for(int w : g.adj(v)){
26+
if(this.hasCycle()) return;
27+
else if(!marked[w]){ //当前结点未被访问过,一定不是闭环,递归调用
28+
edgeTo[w] = v;
29+
dfs(g, w);
30+
}
31+
else if(onStack[w]){ //在此次的遍历中,当前点已经在环上,说明已经构成了cycle.v的下一个结点构成了闭环。
32+
//创建stack对象,并添加元素。
33+
cycle = new Stack<>();
34+
for(int x = v; x != w; x = edgeTo[x])
35+
cycle.push(x);
36+
cycle.push(w);
37+
cycle.push(v);
38+
}
39+
}
40+
onStack[v] = false;
41+
}
42+
43+
public boolean hasCycle(){
44+
return cycle != null;
45+
}
46+
47+
public Iterable<Integer> cycle(){
48+
return cycle;
49+
}
50+
51+
public static void main(String[] args) throws FileNotFoundException {
52+
Digraph g = new DigraphImpl(new FileInputStream(new File("src/ca/mcmaster/chapter/four/graph/tinyDG.txt")));
53+
DirectedCycle cycle = new DirectedCycle(g);
54+
StringBuilder sb = new StringBuilder();
55+
for(int i : cycle.cycle()){
56+
sb.append(i + " ");
57+
}
58+
System.out.println(sb.toString());
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
13
2+
15
3+
2 3
4+
0 6
5+
0 1
6+
2 0
7+
11 12
8+
9 12
9+
9 10
10+
9 11
11+
3 5
12+
8 7
13+
5 4
14+
0 5
15+
6 4
16+
6 9
17+
7 6
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package ca.mcmaster.chapter.four.graph.directed;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileNotFoundException;
6+
import java.util.Stack;
7+
8+
public class DirectedCycle {
9+
private final boolean[] marked;
10+
private final int[] edgeTo;
11+
private Stack<Integer> cycle = null; //有向环上的所有顶点
12+
private final boolean[] onStack; //递归调用的栈上的所有顶点
13+
public DirectedCycle(Digraph g){
14+
onStack = new boolean[g.V()];
15+
marked = new boolean[g.V()];
16+
edgeTo = new int[g.V()];
17+
int size = g.V();
18+
for(int v = 0; v < size; v++)
19+
if(!marked[v]) dfs(g, v);
20+
}
21+
private void dfs(Digraph g, int v){
22+
//在此次的遍历中,记录当前的位置可能在环上。如果结束了没有在环上则改回false
23+
onStack[v] = true;
24+
marked[v] = true;
25+
for(int w : g.adj(v)){
26+
if(this.hasCycle()) return;
27+
else if(!marked[w]){ //当前结点未被访问过,一定不是闭环,递归调用
28+
edgeTo[w] = v;
29+
dfs(g, w);
30+
}
31+
else if(onStack[w]){ //在此次的遍历中,当前点已经在环上,说明已经构成了cycle.v的下一个结点构成了闭环。
32+
//创建stack对象,并添加元素。
33+
cycle = new Stack<>();
34+
for(int x = v; x != w; x = edgeTo[x])
35+
cycle.push(x);
36+
cycle.push(w);
37+
cycle.push(v);
38+
}
39+
}
40+
onStack[v] = false;
41+
}
42+
43+
public boolean hasCycle(){
44+
return cycle != null;
45+
}
46+
47+
public Iterable<Integer> cycle(){
48+
return cycle;
49+
}
50+
51+
public static void main(String[] args) throws FileNotFoundException {
52+
Digraph g = new DigraphImpl(new FileInputStream(new File("src/ca/mcmaster/chapter/four/graph/tinyDG.txt")));
53+
DirectedCycle cycle = new DirectedCycle(g);
54+
StringBuilder sb = new StringBuilder();
55+
for(int i : cycle.cycle()){
56+
sb.append(i + " ");
57+
}
58+
System.out.println(sb.toString());
59+
}
60+
}

DataStructrue/Graph/DirectedGraph.md

+61-2
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ public class BreadFirstPathDirectedGraph implements Path {
257257
public boolean hasPathTo(int v) {
258258
return marked[v];
259259
}
260-
261260
@Override
262261
public Iterable<Integer> pathTo(int v) {
263262
Stack<Integer> path = new Stack<>();
@@ -286,4 +285,64 @@ public class BreadFirstPathDirectedGraph implements Path {
286285
}
287286
```
288287

289-
* 测试和DFS完全一致。
288+
* 测试和DFS完全一致。
289+
290+
### 寻找有向环
291+
```Java
292+
public class DirectedCycle {
293+
private final boolean[] marked;
294+
private final int[] edgeTo;
295+
private Stack<Integer> cycle = null; //有向环上的所有顶点
296+
private final boolean[] onStack; //递归调用的栈上的所有顶点
297+
public DirectedCycle(Digraph g){
298+
onStack = new boolean[g.V()];
299+
marked = new boolean[g.V()];
300+
edgeTo = new int[g.V()];
301+
int size = g.V();
302+
for(int v = 0; v < size; v++)
303+
if(!marked[v]) dfs(g, v);
304+
}
305+
private void dfs(Digraph g, int v){
306+
//在此次的遍历中,记录当前的位置可能在环上。如果结束了没有在环上则改回false
307+
onStack[v] = true;
308+
marked[v] = true;
309+
for(int w : g.adj(v)){
310+
if(this.hasCycle()) return;
311+
else if(!marked[w]){ //当前结点未被访问过,一定不是闭环,递归调用
312+
edgeTo[w] = v;
313+
dfs(g, w);
314+
}
315+
else if(onStack[w]){ //在此次的遍历中,当前点已经在环上,说明已经构成了cycle.v的下一个结点构成了闭环。
316+
//创建stack对象,并添加元素。
317+
cycle = new Stack<>();
318+
for(int x = v; x != w; x = edgeTo[x])
319+
cycle.push(x);
320+
cycle.push(w);
321+
cycle.push(v);
322+
}
323+
}
324+
onStack[v] = false;
325+
}
326+
public boolean hasCycle(){
327+
return cycle != null;
328+
}
329+
public Iterable<Integer> cycle(){
330+
return cycle;
331+
}
332+
}
333+
```
334+
335+
* 测试
336+
337+
```Java
338+
public static void main(String[] args) throws FileNotFoundException {
339+
Digraph g = new DigraphImpl(new FileInputStream(new File("src/ca/mcmaster/chapter/four/graph/tinyDG.txt")));
340+
DirectedCycle cycle = new DirectedCycle(g);
341+
StringBuilder sb = new StringBuilder();
342+
for(int i : cycle.cycle()){
343+
sb.append(i + " ");
344+
}
345+
System.out.println(sb.toString());
346+
}
347+
```
348+
> 3 4 5 3

0 commit comments

Comments
 (0)