The difference between this question and already answered question is in the implementation. I am using recursion, and also an ArrayList
of an ArrayList
.
I am currently working on printing an eulerian cycle from a graph but am running into some issues. The idea is to start from a given node, go to one if its neighbors, check if its a bridge node or not, then remove the edge from the 2 nodes if it is not. By removing the edges each occurrence I will end up with my expected results. The problem is removing the edge (I think) from the adjacency list. I'm really stumped on how to get around this issue. My first thought was to just pass each function a new ArrayList
instead of accessing the instance variable each pass/recurse, but it did not solve the issue. Here's an example of an input and expected output.
Starting a node 3 with the following adjacency list:
0 -> 3
1 -> 0
2 -> 1,6
3 -> 2
4 -> 2
5 -> 4
6 -> 5,8
7 -> 9
8 -> 7
9 -> 6
The output should look like:
3 -> 2 -> 6-> 8-> 7-> 9-> 6-> 5-> 4-> 2-> 1-> 0-> 3
You should start and end at the same node.
Here is my code.
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
public class EU {
static File inputFile = new File(filepath);
int totalNodes;
Vector<String> nodeList;
List<ArrayList<Integer>> adjList;
private ArrayList<Integer>[] adj;
ArrayList<String> visited;
private void addEdge(int u, int v)
{
adj[u].add((Integer) v);
}
// This function removes edge u-v from graph.
private ArrayList<Integer>[] removeEdge(int u, int v)
{
adj[u].remove((Integer) v);
return adj;
}
private EU() throws IOException {
totalNodes = 0;
visited = new ArrayList<>();
adjList = new ArrayList<>();
nodeList = new Vector<>();
Scanner l = new Scanner(Path.of(inputFile.toURI()));
Scanner b = new Scanner(Path.of(inputFile.toURI()));
while(l.hasNext()){
String in1 = l.nextLine();
totalNodes++;
}
adj = new ArrayList[totalNodes];
for(int i = 0; i < totalNodes; i++){
adj[i] = new ArrayList<>();
}
while(b.hasNext()){
String in = b.nextLine();
String[] node = in.split(" -> ", 2 );
String[] neighbors = node[1].split(",", node[1].length());
for(int i = 0; i < neighbors.length; i++){
addEdge(Integer.parseInt(node[0]), Integer.parseInt(neighbors[i]));
}
}
}
private boolean isValidNextEdge(Integer u, Integer v,ArrayList<Integer>[] ad )
{
// The edge u-v is valid in one of the
// following two cases:
// 1) If v is the only adjacent vertex of u
// ie size of adjacent vertex list is 1
if (ad[u].size() == 1) {
return true;
}
// 2) If there are multiple adjacents, then
// u-v is not a bridge Do following steps
// to check if u-v is a bridge
// 2.a) count of vertices reachable from u
boolean[] isVisited = new boolean[totalNodes];
int count1 = dfsCount(u, isVisited, ad);
// 2.b) Remove edge (u, v) and after removing
// the edge, count vertices reachable from u
isVisited = new boolean[totalNodes];
int count2 = dfsCount(v, isVisited, removeEdge(u, v));
// 2.c) Add the edge back to the graph
addEdge(u, v);
return count1 <= count2;
}
private int dfsCount(Integer v, boolean[] isVisited,ArrayList<Integer>[] ad )
{
// Mark the current node as visited
isVisited[v] = true;
int count = 1;
// Recur for all vertices adjacent to this vertex
for (int a : ad[v]) {
if (!isVisited[a]) {
count = count + dfsCount(a, isVisited, ad);
}
}
return count;
}
public void printe(int u, ArrayList<Integer>[] ad){
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < ad[u].size(); i++) {
list = ad[u];
// If edge u-v is a valid next edge
for(Integer neighbors : list) {
if (isValidNextEdge(u, neighbors, ad)) {
System.out.print(u + "-" + neighbors + " ");
// This edge is used so remove it now
removeEdge(u, neighbors);
printe(neighbors, removeEdge(u, neighbors));
}
}
}
}
public static void main(String[] args) throws IOException {
EU r = new EU();
int in = r.adj[0].get(0);
r.printe(in, r.adj);
}
}