T
- The type of elements in this digraph.public class Digraph<T> extends Object
Edges can be dynamically added with AbstractDigraph.add(Object,Object)
. Cycle
can be found with AbstractDigraph.hasCycle()
and AbstractDigraph.getCycle()
.
If no cycle exists, a topological order can be found with
AbstractDigraph.getTopologicalOrder()
.
This implementation uses Integer
-based vertex indices as references
to the arbitrary-typed object vertices via HashBiMap
.
The digraph is internally represented as a dynamically scalable
ArrayList
list of index->LinkedHashSet
set of adjacent
edges.
All operations take constant time (in the worst case) except iterating over the vertices adjacent from a given vertex, which takes time proportional to the number of such vertices.
The Digraph
implements Map<T,Set<T>>
, supporting all required
and optional operations.
Modifier and Type | Field and Description |
---|---|
protected ArrayList<LinkedHashSet<Integer>> |
adj |
protected TransList<LinkedHashSet<Integer>,TransSet<Integer,V>> |
adjEdges |
protected ArrayIntList |
adjRemoved |
protected ArrayList<K> |
cycle |
protected Object[][] |
flatAdj |
protected ArrayIntList |
inDegree |
protected Map<Integer,Object> |
indexToObject |
protected HashBiMap<Object,Integer> |
objectToIndex |
protected ObservableMap<K,Integer> |
observableObjectToIndex |
protected ArrayList<K> |
reversePostOrder |
protected org.libj.util.AbstractDigraph<K,V> |
transverse |
Modifier and Type | Method and Description |
---|---|
boolean |
add(K vertex)
Add a vertex to the graph.
|
boolean |
add(K from,
V to)
Add directed edge (
from -> to ) to this digraph. |
void |
clear()
Removes all vertices and associated edges in this digraph.
|
Digraph<T> |
clone()
Returns a clone of this digraph.
|
boolean |
containsKey(Object vertex)
Returns
true if this digraph contains the specified vertex . |
boolean |
containsValue(Object edges)
Returns
true if at least one vertex in this digraph contains the
specified edges . |
Set<Map.Entry<K,Set<V>>> |
entrySet()
Returns a set of
Map.Entry objects representing the
(vertex ->> edges ) mappings in this digraph. |
boolean |
equals(Object obj)
Tests whether
this digraph is equal to obj . |
Set<V> |
get(Object vertex)
Returns the set of edges mapped to the specified
vertex . |
List<K> |
getCycle()
Returns a directed cycle if the digraph has one, and
null
otherwise. |
int |
getInDegree(K vertex)
Returns the number of directed edges incident to vertex
vertex . |
int |
getOutDegree(K vertex)
Returns the number of directed edges incident from vertex
vertex . |
List<K> |
getTopologicalOrder()
Returns the reverse post order of a depth first search analysis of the
digraph, or
null if no such order exists due to a cycle. |
boolean |
hasCycle()
Specifies whether the digraph has a cycle.
|
int |
hashCode()
Returns the hash code value for this digraph.
|
protected T |
indexToKey(int v)
Dereference a vertex index to the key of type
K . |
protected T |
indexToValue(int v)
Dereference a vertex index to the value of type
V . |
protected static <K,V> void |
init(org.libj.util.AbstractDigraph<K,V> digraph) |
boolean |
isEmpty()
Returns
true if this digraph contains no vertices. |
Set<K> |
keySet()
Returns the set of vertices in this digraph.
|
Set<V> |
put(K vertex,
Set<V> edges)
Associate the set of directed
edges to the vertex . |
void |
putAll(Map<? extends K,? extends Set<V>> m)
Copies all of the mappings from the specified map to this digraph.
|
Set<V> |
remove(Object vertex)
Remove the vertex and its associated edges from this digraph.
|
int |
size()
Returns the number of vertices in this digraph.
|
String |
toString()
Returns a string representation of this digraph, containing: the number of
vertices, followed by the number of edges, followed by the adjacency lists.
|
org.libj.util.AbstractDigraph<K,V> |
transverse()
Returns the transverse of this digraph.
|
Collection<Set<V>> |
values()
Returns a collection of edges in this digraph.
|
finalize, getClass, notify, notifyAll, wait, wait, wait
compute, computeIfAbsent, computeIfPresent, forEach, getOrDefault, merge, putIfAbsent, remove, replace, replace, replaceAll
protected org.libj.util.AbstractDigraph<K,V> transverse
protected ArrayIntList adjRemoved
protected ArrayList<LinkedHashSet<Integer>> adj
protected TransList<LinkedHashSet<Integer>,TransSet<Integer,V>> adjEdges
protected ObservableMap<K,Integer> observableObjectToIndex
protected ArrayIntList inDegree
protected Object[][] flatAdj
protected ArrayList<K> cycle
protected ArrayList<K> reversePostOrder
protected T indexToKey(int v)
K
.v
- The vertex index.K
at the specified vertex index.protected T indexToValue(int v)
V
.v
- The vertex index.K
at the specified vertex
index.public Digraph<T> clone()
protected static <K,V> void init(org.libj.util.AbstractDigraph<K,V> digraph)
public boolean add(K from, V to)
from -> to
) to this digraph. Calling this with
to = null
is the equivalent of calling
AbstractDigraph.add(from)
.
Note: This method is not thread safe.
from
- The tail vertex.to
- The head vertex.true
if this digraph has been modified, and false
if the specified edge already existed in the digraph.public boolean add(K vertex)
Note: This method is not thread safe.
vertex
- The vertex.true
if this digraph has been modified, and false
if the specified vertex already existed in the digraph.public Set<V> put(K vertex, Set<V> edges)
edges
to the vertex
.
vertex ->> edges
If the digraph previously contained a mapping for the vertex, the old edges
are replaced by the specified value.
Note: This method is not thread safe.
public void putAll(Map<? extends K,? extends Set<V>> m)
AbstractDigraph.put(Object,Set)
on this map once for each mapping
from key
to value
in the specified map. The behavior of
this operation is undefined if the specified map is modified while the
operation is in progress.
Note: This method is not thread safe.
public Set<V> get(Object vertex)
vertex
.
Modifications made to this digraph are reflected in the set, and
modifications made to the set are reflected in this digraph.public boolean containsKey(Object vertex)
true
if this digraph contains the specified vertex
.containsKey
in interface Map<K,Set<V>>
vertex
- The vertex.true
if this digraph contains the specified vertex
.public boolean containsValue(Object edges)
true
if at least one vertex in this digraph contains the
specified edges
.
Note: If a vertex is not associated to any edges, its value is not
null
, but rather an empty set. Therefore, this method will return
null
if the specified edges
is null.
Note: The expected type of the edges
is Set<V>
, but
this method accepts type Object
to match the interface for
Map.containsValue(Object)
.
containsValue
in interface Map<K,Set<V>>
edges
- The edges.true
if at least one vertex in this digraph contains the
specified edges
.public Set<K> keySet()
public Collection<Set<V>> values()
public Set<Map.Entry<K,Set<V>>> entrySet()
Map.Entry
objects representing the
(vertex ->> edges
) mappings in this digraph.
Modifications made to this digraph are reflected in the set, and
modifications made to the set are reflected in this digraph.public Set<V> remove(Object vertex)
public void clear()
public int size()
public boolean isEmpty()
true
if this digraph contains no vertices.public int getInDegree(K vertex)
vertex
.vertex
- The vertex.vertex
.NoSuchElementException
- If vertex vertex
does not exist in
this digraph.public int getOutDegree(K vertex)
vertex
.vertex
- The vertex.vertex
.NoSuchElementException
- If vertex vertex
does not exist in
this digraph.public List<K> getCycle()
null
otherwise.null
.public boolean hasCycle()
true
if the digraph has a cycle; otherwise false
.public List<K> getTopologicalOrder()
null
if no such order exists due to a cycle.
Note: This method is not thread safe.
null
if no such order exists due to a cycle.public org.libj.util.AbstractDigraph<K,V> transverse()
public boolean equals(Object obj)
this
digraph is equal to obj
.public int hashCode()
public String toString()
Copyright © 2020 LibJ. All rights reserved.