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