Skip to content

Commit ca8b719

Browse files
committed
euler
1 parent 137d335 commit ca8b719

File tree

8 files changed

+123
-17
lines changed

8 files changed

+123
-17
lines changed

.idea/workspace.xml

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

g5.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+
0 2
4+
1 2
5+
2 3
6+
2 4
7+
3 4

out/production/Graph/CC.class

-58 Bytes
Binary file not shown.

out/production/Graph/EulerLoop.class

2.17 KB
Binary file not shown.

out/production/Graph/Graph.class

608 Bytes
Binary file not shown.

src/CC.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ private void dfs(int v,int ccid){
3434
// 返回几个联通分量
3535
public int count(){
3636
for(int e : visited){
37-
System.out.print(e + " ");
37+
//System.out.print(e + " ");
3838
}
39-
System.out.println();
39+
4040
return cccount;
4141
}
4242

src/EulerLoop.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import java.util.ArrayList;
2+
import java.util.Stack;
3+
4+
// 欧拉回路
5+
public class EulerLoop {
6+
private Graph G;
7+
8+
public EulerLoop(Graph G){
9+
this.G = G ;
10+
}
11+
12+
// 判断是否有欧拉回路
13+
public boolean hasEulerLoop(){
14+
// 必须是联通图
15+
CC cc = new CC(G);
16+
if(cc.count() > 1) return false;
17+
18+
// 只需判读图中所有顶点的度数都是偶数
19+
for(int v = 0; v < G.V(); v ++)
20+
if(G.degree(v) % 2 == 1) return false;
21+
return true;
22+
}
23+
24+
// Hierholzer算法
25+
public ArrayList<Integer> result(){
26+
27+
ArrayList<Integer> res = new ArrayList<>();
28+
if(!hasEulerLoop()) return res;
29+
30+
Graph g = (Graph)G.clone();
31+
32+
Stack<Integer> stack = new Stack<>();
33+
34+
int curv = 0; // 当前顶点
35+
stack.push(curv);
36+
37+
while(!stack.isEmpty()){
38+
// 如果度不为0,说明有路走
39+
if(g.degree(curv) != 0){
40+
stack.push(curv);
41+
//System.out.println(stack);
42+
int w = g.adj(curv).iterator().next(); // 随便取出一条边
43+
g.removeEdge(curv, w); // 删除这条边
44+
curv = w;
45+
}
46+
else{ // 这条边走到底了,说明找到了一个环
47+
res.add(curv);
48+
curv = stack.pop();
49+
// 回退,逐步回退的时候将这个环的点加到list,另回退的时候会有一个公共点,连接着另外的环,
50+
// 接着走这个另外的环,另外的环走完会回到公共点
51+
// 从公共点继续回退,形成路径
52+
// (欧拉回路性质,每个点度数是偶数,相当于几个连接的环组成,通过走环及环的公共点)
53+
}
54+
}
55+
return res;
56+
}
57+
58+
public static void main(String[] args){
59+
60+
Graph g = new Graph("g5.txt");
61+
EulerLoop eulerLoop = new EulerLoop(g);
62+
System.out.println(eulerLoop.result());
63+
}
64+
}

src/Graph.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import java.util.Scanner;
55

66
// 邻接表 , 使用红黑树实现作为默认的建图类 , 另外还有2种邻接矩阵和链表实现的邻接表
7-
public class Graph {
7+
public class Graph implements Cloneable{
88

99
private int V; // 顶点
1010
private int E; // 边
@@ -80,6 +80,14 @@ public int degree(int v){
8080
}
8181

8282

83+
public void removeEdge(int v,int w){
84+
validateVertex(v);
85+
validateVertex(w);
86+
87+
adj[v].remove(w);
88+
adj[w].remove(v);
89+
}
90+
8391
@Override
8492
public String toString(){
8593
StringBuilder sb = new StringBuilder();
@@ -94,6 +102,27 @@ public String toString(){
94102
return sb.toString();
95103
}
96104

105+
@Override
106+
public Object clone(){
107+
108+
try{
109+
Graph cloned = (Graph)super.clone();
110+
cloned.adj = new TreeSet[V];
111+
for(int v = 0; v < V; v ++){
112+
cloned.adj[v] = new TreeSet<Integer>();
113+
for(int w: adj[v])
114+
cloned.adj[v].add(w);
115+
}
116+
return cloned;
117+
118+
}catch(CloneNotSupportedException e){
119+
e.printStackTrace();
120+
}
121+
122+
return null;
123+
124+
}
125+
97126
public static void main(String[] args){
98127

99128
Graph graph = new Graph("g.txt");

0 commit comments

Comments
 (0)