programming-examples/java/Data_Structures/EulerCycle.java

119 lines
2.9 KiB
Java
Raw Normal View History

2019-11-15 12:59:38 +01:00
import java.util.*;
import java.util.stream.Stream;
public class EulerCycle {
public static List<Integer> eulerCycleUndirected(List<Integer>[] graph, int u) {
Set<Long> usedEdges = new HashSet<>();
int n = graph.length;
int[] curEdge = new int[n];
List<Integer> res = new ArrayList<>();
dfs(graph, curEdge, usedEdges, res, u);
Collections.reverse(res);
return res;
}
static void dfs(List<Integer>[] graph, int[] curEdge, Set<Long> usedEdges, List<Integer> res, int u) {
while (curEdge[u] < graph[u].size()) {
int v = graph[u].get(curEdge[u]++);
if (usedEdges.add(((long) Math.min(u, v) << 32) + Math.max(u, v)))
dfs(graph, curEdge, usedEdges, res, v);
}
res.add(u);
}
public static List<Integer> eulerCycleUndirected2(List<Integer>[] graph, int u) {
int[] curEdge = new int[graph.length];
List<Integer> res = new ArrayList<>();
Stack<Integer> stack = new Stack<>();
Set<Long> usedEdges = new HashSet<>();
stack.add(u);
while (!stack.isEmpty()) {
u = stack.pop();
while (curEdge[u] < graph[u].size()) {
int v = graph[u].get(curEdge[u]++);
if (usedEdges.add((((long) Math.min(u, v) << 32) + Math.max(u, v)))) {
stack.push(u);
u = v;
}
}
res.add(u);
}
Collections.reverse(res);
return res;
}
public static List<Integer> eulerCycleDirected(List<Integer>[] graph, int u) {
int n = graph.length;
int[] curEdge = new int[n];
List<Integer> res = new ArrayList<>();
dfs(graph, curEdge, res, u);
Collections.reverse(res);
return res;
}
static void dfs(List<Integer>[] graph, int[] curEdge, List<Integer> res, int u) {
while (curEdge[u] < graph[u].size()) {
dfs(graph, curEdge, res, graph[u].get(curEdge[u]++));
}
res.add(u);
}
public static List<Integer> eulerCycleDirected2(List<Integer>[] graph, int v) {
int[] curEdge = new int[graph.length];
List<Integer> res = new ArrayList<>();
Stack<Integer> stack = new Stack<>();
stack.add(v);
while (!stack.isEmpty()) {
v = stack.pop();
while (curEdge[v] < graph[v].size()) {
stack.push(v);
v = graph[v].get(curEdge[v]++);
}
res.add(v);
}
Collections.reverse(res);
return res;
}
// Usage example
public static void main(String[] args) {
int n = 5;
List<Integer>[] g = Stream.generate(ArrayList::new).limit(n).toArray(List[]::new);
g[0].add(1);
g[1].add(2);
g[2].add(0);
g[1].add(3);
g[3].add(4);
g[4].add(1);
System.out.println(eulerCycleDirected(g, 0));
System.out.println(eulerCycleDirected2(g, 0));
n = 5;
g = Stream.generate(ArrayList::new).limit(n).toArray(List[]::new);
g[0].add(1);
g[1].add(0);
g[1].add(2);
g[2].add(1);
g[2].add(3);
g[3].add(2);
g[0].add(3);
g[3].add(0);
g[0].add(4);
g[4].add(0);
g[1].add(4);
g[4].add(1);
g[0].add(2);
g[2].add(0);
g[1].add(3);
g[3].add(1);
System.out.println(eulerCycleUndirected(g, 2));
System.out.println(eulerCycleUndirected2(g, 2));
}
}