Files
upo-graphs/src/berack96/lib/graph/impl/ListGraph.java
Giacomo Bertolazzi 9bda59dc7b Refactoring
* Upgraded to JUnit5
* Enhanced the tests for multiple instances of graphs
* Save/Load test now pass

* Changed the hierarchy of classes:
  - Graph is now the main Abstract class for the graphs
  - GraphDirected is an Abstract class for directed graph and inherits Graph
  - GraphUndirected is an Abstract class for undirected graph and inherits Graph
* Changed how the Weight is represented in the graphs, removing the second parameter. From now on is only int.
* Updated the implementations for MatrixGraph, ListGraph and MapGraph
* Implemented only one undirected graph MatrixUndGraph
* Added UnionFind and one implementation: QuickFind
* Added MSF visit and implemented Kruskal and Prim (no tests)

* Changed all the graphic components due to the deletion of the second parameter in the Graph class
2021-01-12 17:09:09 +01:00

161 lines
3.6 KiB
Java

package berack96.lib.graph.impl;
import berack96.lib.graph.Graph;
import berack96.lib.graph.GraphDirected;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* An implementation of the graph using an adjacent list for representing the edges
*
* @param <V> the vertex
* @author Berack96
*/
public class ListGraph<V> extends GraphDirected<V> {
final private Map<V, List<Adj>> adj = new Hashtable<>();
@Override
public Iterator<V> iterator() {
return adj.keySet().iterator();
}
@Override
protected Graph<V> getNewInstance() {
return new ListGraph<>();
}
@Override
public void add(V vertex) {
check(vertex);
if (adj.containsKey(vertex))
removeAllEdge(vertex);
else
adj.put(vertex, new LinkedList<>());
}
@Override
public boolean contains(V vertex) {
check(vertex);
return adj.containsKey(vertex);
}
@Override
public void remove(V vertex) {
checkVert(vertex);
adj.remove(vertex);
adj.forEach((v, list) -> list.remove(getAdj(list, vertex)));
}
@Override
public int addEdge(V vertex1, V vertex2, int weight) {
checkVert(vertex1, vertex2);
List<Adj> list = adj.get(vertex1);
Adj a = getAdj(list, vertex2);
int old = a == null ? NO_EDGE : a.weight;
if (weight == NO_EDGE)
list.remove(a);
else if (old == NO_EDGE)
list.add(new Adj(vertex2, weight));
else
a.weight = weight;
return old;
}
@Override
public int getWeight(V vertex1, V vertex2) {
checkVert(vertex1, vertex2);
Adj a = getAdj(adj.get(vertex1), vertex2);
return a == null ? NO_EDGE : a.weight;
}
@Override
public Collection<V> getChildren(V vertex) throws NullPointerException, IllegalArgumentException {
checkVert(vertex);
Collection<V> children = new HashSet<>();
for (Adj adj : adj.get(vertex))
children.add(adj.vertex);
return children;
}
@Override
public Collection<V> getAncestors(V vertex) throws NullPointerException, IllegalArgumentException {
checkVert(vertex);
Collection<V> ancestors = new HashSet<>();
adj.forEach((v, list) -> {
if (getAdj(list, vertex) != null)
ancestors.add(v);
});
return ancestors;
}
/**
* From here on there are some optimization for the methods of the generic DirectedGraph
**/
@Override
public int size() {
return adj.size();
}
@Override
public int numberOfEdges() {
AtomicInteger size = new AtomicInteger(0);
adj.values().forEach(list -> size.addAndGet(list.size()));
return size.get();
}
@Override
public int degreeIn(V vertex) throws NullPointerException, IllegalArgumentException {
checkVert(vertex);
AtomicInteger degree = new AtomicInteger(0);
adj.values().forEach(list -> degree.addAndGet(getAdj(list, vertex) != null ? 1 : 0));
return degree.get();
}
@Override
public int degreeOut(V vertex) throws NullPointerException, IllegalArgumentException {
checkVert(vertex);
return adj.get(vertex).size();
}
@Override
public void removeAllEdge(V vertex) throws NullPointerException, IllegalArgumentException {
checkVert(vertex);
adj.get(vertex).clear();
adj.forEach((v, list) -> list.remove(getAdj(list, vertex)));
}
@Override
public void removeAllEdge() {
adj.forEach((v, list) -> list.clear());
}
@Override
public void removeAll() {
adj.clear();
}
private Adj getAdj(List<Adj> list, V vertex) {
for (Adj adj : list)
if (Objects.equals(adj.vertex, vertex))
return adj;
return null;
}
private class Adj {
private final V vertex;
private int weight;
private Adj(V vertex, int weight) {
this.vertex = vertex;
this.weight = weight;
}
}
}