-
Notifications
You must be signed in to change notification settings - Fork 0
/
DirectedDenseGraph.java
152 lines (120 loc) · 4.41 KB
/
DirectedDenseGraph.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package com.sleepycoders.jlib.datastructure.graph;
import java.util.ArrayList;
import java.util.List;
/**
* @author Joshua Moody ([email protected])
*/
public class DirectedDenseGraph<TVertex> implements IGraph<TVertex> {
final TVertex EMPTY_VERTEX_SLOT = null;
final int EMPTY_EDGE_SLOT = 0;
final int DEFAULT_EDGE_WEIGHT = 1;
int vertexCapacity;
int vertexCount;
public int vertexCount() {
return vertexCount;
}
int edgeCount;
public int edgeCount() { return edgeCount; }
List<TVertex> vertices;
int[][] adjacencyMatrix;
public DirectedDenseGraph(int capacity) {
vertexCapacity = capacity;
vertexCount = 0;
edgeCount = 0;
vertices = new ArrayList<>(capacity);
adjacencyMatrix = new int[capacity][capacity];
// initalize to empty values
for (int row = 0; row < adjacencyMatrix.length ; row++) {
for (int col = 0; col < adjacencyMatrix[row].length; col++) {
adjacencyMatrix[row][col] = EMPTY_EDGE_SLOT;
}
}
for (int i = 0; i < vertexCapacity; i++) {
vertices.add(EMPTY_VERTEX_SLOT);
}
}
// Vertices
public boolean containsVertex(TVertex v) {
return containsVertex(vertices.indexOf(v));
}
private boolean containsVertex(int v) {
return v != -1 && vertices.get(v) != EMPTY_VERTEX_SLOT;
}
public boolean addVertex(TVertex v) {
// is their space in the graph?
if (vertexCount >= vertexCapacity) { return false; }
// does the graph already contain this vertex?
if (containsVertex(v)) { return false; }
// find a free spot
int freeIndex = vertices.indexOf(EMPTY_VERTEX_SLOT);
vertices.set(freeIndex, v);
vertexCount++;
return true;
}
public boolean removeVertex(TVertex v) {
// is the graph empty?
if (vertexCount == 0) { return false; }
// lazily remove vertex
int index = vertices.indexOf(v);
if (index == -1) { return false; }
vertices.set(index, EMPTY_VERTEX_SLOT);
vertexCount--;
// remove edges
for (int i = 0; i < vertexCapacity; i++) {
removeEdge(index, i);
removeEdge(i, index);
}
return true;
}
// Edges
public boolean containsEdge(TVertex src, TVertex dst) {
return containsEdge(vertices.indexOf(src), vertices.indexOf(dst));
}
private boolean containsEdge(int srcIndex, int dstIndex) {
return srcIndex != -1 && dstIndex != -1 && adjacencyMatrix[srcIndex][dstIndex] != EMPTY_EDGE_SLOT;
}
public boolean addEdge(TVertex src, TVertex dst) {
return addEdge(vertices.indexOf(src), vertices.indexOf(dst));
}
private boolean addEdge(int srcIndex, int dstIndex) {
if (srcIndex == -1 || dstIndex == -1 || containsEdge(srcIndex, dstIndex)) { return false; }
adjacencyMatrix[srcIndex][dstIndex] = DEFAULT_EDGE_WEIGHT;
edgeCount++;
return true;
}
public boolean removeEdge(TVertex src, TVertex dst) {
return removeEdge(vertices.indexOf(src), vertices.indexOf(dst));
}
private boolean removeEdge(int srcIndex, int dstIndex) {
if (srcIndex == -1 || dstIndex == -1 || !containsEdge(srcIndex, dstIndex)) { return false; }
adjacencyMatrix[srcIndex][dstIndex] = EMPTY_EDGE_SLOT;
edgeCount--;
return true;
}
public List<TVertex> neighbours(TVertex src) {
List<TVertex> destinations = new ArrayList<TVertex>();
int srcIndex = vertices.indexOf(src);
if (srcIndex == -1) { return destinations; }
for (int i = 0; i < vertexCapacity; i++) {
if (containsEdge(srcIndex, i)) { destinations.add(vertices.get(i)); }
}
return destinations;
}
/**
* @return a human-readable string of the graph.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (TVertex src : vertices) {
// source vertex
if (src == EMPTY_VERTEX_SLOT) { continue; }
sb.append("\r\n").append(src).append(": [");
// add destinations
for (TVertex dst : neighbours(src)) { sb.append(dst).append(','); }
if (sb.charAt(sb.length() - 1) == ',') { sb.deleteCharAt(sb.length() - 1); }
sb.append("]");
}
return sb.toString();
}
}