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+ }