1
+ import java .util .*;
2
+
3
+ public abstract class AbstractGraph <V >implements Graph <V > {
4
+ protected List <V >vertices =new ArrayList <>();// Store vertices
5
+ protected List <List <Edge >>neighbors =new ArrayList <>();// Adjacendy lists
6
+
7
+ /** Construct an empty graph */
8
+ protected AbstractGraph () {
9
+ }
10
+
11
+ /** Construct a graph from vertices and edges stored in arrays */
12
+ protected AbstractGraph (V []vertices ,int [][]edges ) {
13
+ for (int i =0 ;i <vertices .length ;i ++)
14
+ addVertex (vertices [i ]);
15
+
16
+ createAdjacencyLists (edges ,vertices .length );
17
+ }
18
+
19
+ /** Construct a graph from vertices and edges stored in List */
20
+ protected AbstractGraph (List <V >vertices ,List <Edge >edges ) {
21
+ for (int i =0 ;i <vertices .size ();i ++)
22
+ addVertex (vertices .get (i ));
23
+
24
+ createAdjacencyLists (edges ,vertices .size ());
25
+ }
26
+
27
+ /** Construct a graph for integer vertices 0, 1, 2 and edge list */
28
+ protected AbstractGraph (List <Edge >edges ,int numberOfVertices ) {
29
+ for (int i =0 ;i <numberOfVertices ;i ++)
30
+ addVertex ((V )(new Integer (i )));// vertices is {0, 1, ...}
31
+
32
+ createAdjacencyLists (edges ,numberOfVertices );
33
+ }
34
+
35
+ /** Construct a graph from integer vertices 0, 1, and edge array */
36
+ protected AbstractGraph (int [][]edges ,int numberOfVertices ) {
37
+ for (int i =0 ;i <numberOfVertices ;i ++)
38
+ addVertex ((V )(new Integer (i )));// vertices is {0, 1, ...}
39
+
40
+ createAdjacencyLists (edges ,numberOfVertices );
41
+ }
42
+
43
+ /** Create adjacency lists for each vertex */
44
+ private void createAdjacencyLists (
45
+ int [][]edges ,int numberOfVertices ) {
46
+ for (int i =0 ;i <edges .length ;i ++) {
47
+ addEdge (edges [i ][0 ],edges [i ][1 ]);
48
+ }
49
+ }
50
+
51
+ /** Create adjacency lists for each vertex */
52
+ private void createAdjacencyLists (
53
+ List <Edge >edges ,int numberOfVertices ) {
54
+ for (Edge edge :edges ) {
55
+ addEdge (edge .u ,edge .v );
56
+ }
57
+ }
58
+
59
+ @ Override /** Return the number of vertices in the graph */
60
+ public int getSize () {
61
+ return vertices .size ();
62
+ }
63
+
64
+ @ Override /** Return the vertices in the graph */
65
+ public List <V >getVertices () {
66
+ return vertices ;
67
+ }
68
+
69
+ @ Override /** Return the object of the specified vertex */
70
+ public V getVertex (int index ) {
71
+ return vertices .get (index );
72
+ }
73
+
74
+ @ Override /** Return the index for the specified vertex object */
75
+ public int getIndex (V v ) {
76
+ return vertices .indexOf (v );
77
+ }
78
+
79
+ @ Override /** Return the neighbors of the specified vertex */
80
+ public List <Integer >getNeighbors (int index ) {
81
+ List <Integer >result =new ArrayList <>();
82
+ for (Edge e :neighbors .get (index )) {
83
+ result .add (e .v );
84
+ }
85
+
86
+ return result ;
87
+ }
88
+
89
+ @ Override /** Return the degree for a specified vertex */
90
+ public int getDegree (int v ) {
91
+ return neighbors .get (v ).size ();
92
+ }
93
+
94
+ @ Override /** Print the edges */
95
+ public void printEdges () {
96
+ for (int u =0 ;u <neighbors .size ();u ++) {
97
+ System .out .print (getVertex (u ) +" (" +u +"): " );
98
+ for (Edge e :neighbors .get (u )) {
99
+ System .out .print ("(" +getVertex (e .u ) +", " +
100
+ getVertex (e .v ) +") " );
101
+ }
102
+ System .out .println ();
103
+ }
104
+ }
105
+
106
+ @ Override /** Clear teh graph */
107
+ public void clear () {
108
+ vertices .clear ();
109
+ neighbors .clear ();
110
+ }
111
+
112
+ @ Override /** Add a vertex to the graph */
113
+ public boolean addVertex (V vertex ) {
114
+ if (!vertices .contains (vertex )) {
115
+ vertices .add (vertex );
116
+ neighbors .add (new ArrayList <Edge >());
117
+ return true ;
118
+ }
119
+ else {
120
+ return false ;
121
+ }
122
+ }
123
+
124
+ /** Add an edge to the graph */
125
+ protected boolean addEdge (Edge e ) {
126
+ if (e .u <0 ||e .u >getSize () -1 )
127
+ throw new IllegalArgumentException ("No such index: " +e .u );
128
+
129
+ if (e .u <0 ||e .v >getSize () -1 )
130
+ throw new IllegalArgumentException ("No such index: " +e .u );
131
+
132
+ if (!neighbors .get (e .u ).contains (e )) {
133
+ neighbors .get (e .u ).add (e );
134
+ return true ;
135
+ }
136
+ else {
137
+ return false ;
138
+ }
139
+ }
140
+
141
+ @ Override /** Add an edge to the graph */
142
+ public boolean addEdge (int u ,int v ) {
143
+ return addEdge (new Edge (u ,v ));
144
+ }
145
+
146
+ /** Edge inner class inside the AbstractGraph class */
147
+ public static class Edge {
148
+ public int u ;// Starting vertex of the edge
149
+ public int v ;// Ending vertex of the edge
150
+
151
+ /** Construct an edge for (u, v) */
152
+ public Edge (int u ,int v ) {
153
+ this .u =u ;
154
+ this .v =v ;
155
+ }
156
+
157
+ public boolean equals (Object o ) {
158
+ return u == ((Edge )o ).u &&v == ((Edge )o ).v ;
159
+ }
160
+ }
161
+
162
+ @ Override /** Obtain a DFS tree starting from vertex v */
163
+ public Tree dfs (int v ) {
164
+ List <Integer >searchOrder =new ArrayList <>();
165
+ int []parent =new int [vertices .size ()];
166
+ for (int i =0 ;i <parent .length ;i ++)
167
+ parent [i ] = -1 ;// Initialize parent[i] to -1
168
+
169
+ // Mark visited vertices
170
+ boolean []isVisited =new boolean [vertices .size ()];
171
+
172
+ // Recursively search
173
+ dfs (v ,parent ,searchOrder ,isVisited );
174
+
175
+ // Return a search tree
176
+ return new Tree (v ,parent ,searchOrder );
177
+ }
178
+
179
+ /** Recursive method for DFS search */
180
+ private void dfs (int u ,int []parent ,List <Integer >searchOrder ,
181
+ boolean []isVisited ) {
182
+ // Store the visited vertex
183
+ searchOrder .add (u );
184
+ isVisited [u ] =true ;// Vertex v visited
185
+
186
+ for (Edge e :neighbors .get (u )) {
187
+ if (!isVisited [e .v ]) {
188
+ parent [e .v ] =u ;// The parent of vertex e.v is u
189
+ dfs (e .v ,parent ,searchOrder ,isVisited );// Recursive search
190
+ }
191
+ }
192
+ }
193
+
194
+ @ Override /** Starting bfs search from vertex v */
195
+ public Tree bfs (int v ) {
196
+ List <Integer >searchOrder =new ArrayList <>();
197
+ int []parent =new int [vertices .size ()];
198
+ for (int i =0 ;i <parent .length ;i ++)
199
+ parent [i ] = -1 ;// Initialize parent[i] to -1
200
+
201
+ java .util .LinkedList <Integer >queue =
202
+ new java .util .LinkedList <>();// list used as a queue
203
+ boolean []isVisited =new boolean [vertices .size ()];
204
+ queue .offer (v );// Enqueue v
205
+ isVisited [v ] =true ;// Mark it visited
206
+
207
+ while (!queue .isEmpty ()) {
208
+ int u =queue .poll ();// Dequeue to u
209
+ searchOrder .add (u );// u searched
210
+ for (Edge e :neighbors .get (u )) {
211
+ if (!isVisited [e .u ]) {
212
+ queue .offer (e .v );// Enqueue w
213
+ parent [e .v ] =u ;// The parent of w is u
214
+ isVisited [e .v ] =true ;// Mark it visited
215
+ }
216
+ }
217
+ }
218
+
219
+ return new Tree (v ,parent ,searchOrder );
220
+ }
221
+
222
+ /** Tree inner class inside the AbstractGraph class */
223
+ public class Tree {
224
+ private int root ;// The root of the tree
225
+ private int []parent ;// Store the parent of each vertex
226
+ private List <Integer >searchOrder ;// Store the search order
227
+
228
+ /** Construct a tree with root, parent, and searchOrder */
229
+ public Tree (int root ,int []parent ,List <Integer >searchOrder ) {
230
+ this .root =root ;
231
+ this .parent =parent ;
232
+ this .searchOrder =searchOrder ;
233
+ }
234
+
235
+ /** Return the root of the tree */
236
+ public int getRoot () {
237
+ return root ;
238
+ }
239
+
240
+ /** Return the parent vertex v */
241
+ public int getParent (int v ) {
242
+ return parent [v ];
243
+ }
244
+
245
+ /** Return an array representing search order */
246
+ public List <Integer >getSearchOrder () {
247
+ return searchOrder ;
248
+ }
249
+
250
+ /** Return the number of vertices found */
251
+ public int getNumberOfVerticesFound () {
252
+ return searchOrder .size ();
253
+ }
254
+
255
+ /** Return the path of vertices from a vertex to the root */
256
+ public List <V >getPath (int index ) {
257
+ ArrayList <V >path =new ArrayList <>();
258
+
259
+ do {
260
+ path .add (vertices .get (index ));
261
+ index =parent [index ];
262
+ }
263
+ while (index != -1 );
264
+
265
+ return path ;
266
+ }
267
+
268
+ /** Print a path from the root to vertex v */
269
+ public void printPath (int index ) {
270
+ List <V >path =getPath (index );
271
+ System .out .print ("A path form " +vertices .get (root ) +" to " +
272
+ vertices .get (index ) +": " );
273
+ for (int i =path .size () -1 ;i >=0 ;i --)
274
+ System .out .print (path .get (i ) +" " );
275
+ }
276
+
277
+ /** Print the whole tree */
278
+ public void printTree () {
279
+ System .out .println ("Root is: " +vertices .get (root ));
280
+ System .out .print ("Edges: " );
281
+ for (int i =0 ;i <parent .length ;i ++) {
282
+ if (parent [i ] != -1 ) {
283
+ // Display an edge
284
+ System .out .print ("(" +vertices .get (parent [i ]) +", " +
285
+ vertices .get (i ) +") " );
286
+ }
287
+ }
288
+ System .out .println ();
289
+ }
290
+ }
291
+ }