Skip to content

Commit 6f75b3c

Browse files
committed
dag
1 parent 2af21c0 commit 6f75b3c

10 files changed

+169
-29
lines changed

.idea/workspace.xml

Lines changed: 27 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

g8.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
5 6
2+
0 1
3+
1 2
4+
1 3
5+
2 4
6+
3 2
7+
3 0
254 Bytes
Binary file not shown.
Binary file not shown.

out/production/Graph/Graph.class

367 Bytes
Binary file not shown.
341 Bytes
Binary file not shown.

src/CycleDetection.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ public class CycleDetection {
77
private boolean hasCycle = false;
88

99
public CycleDetection(Graph G){
10+
if(G.isDirected())
11+
throw new IllegalArgumentException("只支持无向图");
12+
1013
this.G = G;
1114
visited = new boolean[G.V()];
1215

@@ -45,5 +48,9 @@ public static void main(String[] args){
4548
CycleDetection cycleDetection = new CycleDetection(g);
4649
System.out.println(cycleDetection.hasCycle());
4750

51+
Graph g2 = new Graph("g8.txt",true);
52+
CycleDetection cycleDetection2 = new CycleDetection(g2);
53+
System.out.println(cycleDetection2.hasCycle());
54+
4855
}
4956
}

src/DirectedCycleDetection.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// 有向图的环检测
2+
public class DirectedCycleDetection {
3+
private Graph G;
4+
private boolean[] visited;
5+
private boolean[] onPath; //是否在当前搜索路径上
6+
private boolean hasCycle = false;
7+
8+
public DirectedCycleDetection(Graph G){
9+
if(!G.isDirected())
10+
throw new IllegalArgumentException("只支持有向图");
11+
12+
this.G = G;
13+
visited = new boolean[G.V()];
14+
onPath = new boolean[G.V()];
15+
16+
// 多包一层for,防止有多个联通分量
17+
for(int v = 0 ;v<G.V();v++){
18+
if(!visited[v])
19+
if(dfs(v,v)) {
20+
hasCycle = true;break;
21+
}
22+
23+
}
24+
}
25+
26+
// 从顶点v开始,判断图中是否有环
27+
private boolean dfs(int v,int parent){
28+
visited[v] = true;
29+
onPath[v] = true;
30+
31+
// 遍历相邻节点
32+
for(int w : G.adj(v)){
33+
if(!visited[w]) {
34+
if (dfs(w, v)) return true; //
35+
}else if( onPath[w]) // 判断是否有环:不是父级且在搜索路径上
36+
return true;
37+
}
38+
39+
onPath[v] = false;
40+
41+
return false;
42+
}
43+
44+
// 是否有环
45+
public boolean hasCycle(){
46+
return hasCycle;
47+
}
48+
49+
50+
public static void main(String[] args){
51+
52+
53+
Graph g2 = new Graph("g8.txt",true);
54+
DirectedCycleDetection cycleDetection2 = new DirectedCycleDetection(g2);
55+
System.out.println(cycleDetection2.hasCycle());
56+
57+
}
58+
}

src/Graph.java

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,19 @@ public class Graph implements Cloneable{
99
private int V; // 顶点
1010
private int E; // 边
1111
private TreeSet<Integer>[] adj; // 领接表
12+
private boolean directed;
13+
private int[] indegrees,outdegrees; // 有向图的出度和入度
14+
15+
16+
// 默认无向图
17+
public Graph(String filename){
18+
this(filename,false);
19+
}
20+
21+
// 更新支持有向图
22+
public Graph(String filename,boolean directed) {
23+
this.directed = directed;
1224

13-
public Graph(String filename) {
1425
File file = new File(filename);
1526
if(!file.exists()) throw new IllegalArgumentException("文件不存在");
1627

@@ -24,6 +35,9 @@ public Graph(String filename) {
2435
adj[i] = new TreeSet<Integer>();
2536
}
2637

38+
indegrees = new int[V];
39+
outdegrees = new int[V];
40+
2741
E = scanner.nextInt(); // 第一行的第二值个为边
2842
if(E < 0) throw new IllegalArgumentException("E must be non-negative");
2943
for(int i = 0; i < E; i ++){ //
@@ -34,7 +48,14 @@ public Graph(String filename) {
3448
if(adj[a].contains(b)) throw new IllegalArgumentException("Parallel Edges are Detected!"); // 判断平行边
3549

3650
adj[a].add(b);
37-
adj[b].add(a);
51+
if(directed){
52+
// 统计入度和出度
53+
outdegrees[a]++;
54+
indegrees[b]++;
55+
}
56+
57+
if(!directed)
58+
adj[b].add(a);
3859
}
3960
}
4061
catch(IOException e){
@@ -43,6 +64,9 @@ public Graph(String filename) {
4364

4465
}
4566

67+
public boolean isDirected(){
68+
return directed;
69+
}
4670

4771
public void validateVertex(int v){
4872
if(v < 0 || v >= V)
@@ -75,24 +99,50 @@ public Iterable<Integer> adj(int v) {
7599

76100
// 返回一个顶点的度,即顶点相邻的点有几个
77101
public int degree(int v){
102+
//如果是有向图
103+
if(directed)
104+
throw new IllegalArgumentException("只支持无向图");
78105
validateVertex(v);
79106
return adj[v].size();
80107
}
81108

109+
public int indegree(int v){
110+
if(!directed)
111+
throw new RuntimeException("indegree only works in directed graph.");
112+
validateVertex(v);
113+
return indegrees[v];
114+
}
115+
116+
public int outdegree(int v){
117+
if(!directed)
118+
throw new RuntimeException("outdegree only works in directed graph.");
119+
validateVertex(v);
120+
return outdegrees[v];
121+
}
122+
82123

83124
public void removeEdge(int v,int w){
84125
validateVertex(v);
85126
validateVertex(w);
86127

128+
if(adj[v].contains(w)){
129+
E --;
130+
if(directed){
131+
indegrees[w] --;
132+
outdegrees[v] --;
133+
}
134+
}
135+
87136
adj[v].remove(w);
88-
adj[w].remove(v);
137+
if(!directed)
138+
adj[w].remove(v);
89139
}
90140

91141
@Override
92142
public String toString(){
93143
StringBuilder sb = new StringBuilder();
94144

95-
sb.append(String.format("V = %d, E = %d\n", V, E));
145+
sb.append(String.format("V = %d, E = %d , directed = %b \n", V, E,directed));
96146
for(int i = 0; i < V; i ++){
97147
sb.append(String.format("%d :", i));
98148
for(int w : adj[i])
@@ -125,7 +175,10 @@ public Object clone(){
125175

126176
public static void main(String[] args){
127177

128-
Graph graph = new Graph("g.txt");
178+
// Graph graph = new Graph("g.txt");
179+
// System.out.print(graph);
180+
181+
Graph graph = new Graph("g8.txt",true);
129182
System.out.print(graph);
130183
}
131184
}

src/WeightedGraph.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ public class WeightedGraph implements Cloneable{
1010
private int V; // 顶点
1111
private int E; // 边
1212
private TreeMap<Integer,Integer>[] adj; //adj数组,里面保存着TreeMap。treemap参数 相邻的顶点 ,权值
13+
private boolean directed;
1314

14-
public WeightedGraph(String filename) {
15+
public WeightedGraph(String filename,boolean directed) {
16+
this.directed = directed;
1517
File file = new File(filename);
1618
if(!file.exists()) throw new IllegalArgumentException("文件不存在");
1719

@@ -45,6 +47,13 @@ public WeightedGraph(String filename) {
4547

4648
}
4749

50+
public WeightedGraph(String filename){
51+
this(filename,false);
52+
}
53+
54+
public boolean isDirected(){
55+
return directed;
56+
}
4857

4958
public void validateVertex(int v){
5059
if(v < 0 || v >= V)
@@ -83,6 +92,7 @@ public int getWeight(int v,int w){
8392
}
8493

8594
// 返回一个顶点的度,即顶点相邻的点有几个
95+
// ?
8696
public int degree(int v){
8797
validateVertex(v);
8898
return adj[v].size();
@@ -119,7 +129,7 @@ public int degree(int v){
119129
public String toString(){
120130
StringBuilder sb = new StringBuilder();
121131

122-
sb.append(String.format("V = %d, E = %d\n", V, E));
132+
sb.append(String.format("V = %d, E = %d , directed = %b \n", V, E,directed));
123133
for(int i = 0; i < V; i ++){
124134
sb.append(String.format("%d :", i));
125135
for(Map.Entry<Integer,Integer> entry : adj[i].entrySet() ) //遍历map

0 commit comments

Comments
 (0)