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+ public AbstractGraph () {
9+ }
10+
11+ /** Construct a graph from vertices and edges stored in arrays */
12+ public AbstractGraph (V []vertices ,int [][]edges ) {
13+ for (int i =0 ;i <vertices .length ;i ++) {
14+ addVertex (vertices [i ]);
15+ }
16+
17+ createAdjacencyLists (edges ,vertices .length );
18+ }
19+
20+ /** Construct a graph from vertices and edges stored in lists */
21+ public AbstractGraph (List <V >vertices ,List <Edge >edges ) {
22+ for (int i =0 ;i <vertices .size ();i ++) {
23+ addVertex (vertices .get (i ));
24+ }
25+
26+ createAdjacencyLists (edges ,vertices .size ());
27+ }
28+
29+ /** Construct a graph for integer vertices 0, 1, 2 and edge list */
30+ public AbstractGraph (List <Edge >edges ,int numberOfVertices ) {
31+ for (int i =0 ;i <numberOfVertices ;i ++) {
32+ addVertex ((V )(new Integer (i )));// vertices is {0, 1, ...}
33+ }
34+
35+ createAdjacencyLists (edges ,numberOfVertices );
36+ }
37+
38+ /** Construct a graph for integer vertices 0, 1, 2 and edge array */
39+ public AbstractGraph (int [][]edges ,int numberOfVertices ) {
40+ for (int i =0 ;i <numberOfVertices ;i ++) {
41+ addVertex ((V )(new Integer (i )));// vertices is {0, 1, ...}
42+ }
43+
44+ createAdjacencyLists (edges ,numberOfVertices );
45+ }
46+
47+ /** Create adjacency lists for each vertex */
48+ private void createAdjacencyLists (int [][]edges ,int numberOfVertices ) {
49+ for (int i =0 ;i <edges .length ;i ++) {
50+ addEdge (edges [i ][0 ],edges [i ][1 ]);
51+ }
52+ }
53+
54+ /** Create adjacency lists for each vertex */
55+ private void createAdjacencyLists (List <Edge >edges ,int numberOfVertices ) {
56+ for (Edge edge :edges ) {
57+ addEdge (edge .u ,edge .v );
58+ }
59+ }
60+
61+ @ Override /* Return the number of vertices in the graph */
62+ public int getSize () {
63+ return vertices .size ();
64+ }
65+
66+ @ Override /** Return the vertices in the graph */
67+ public List <V >getVertices () {
68+ return vertices ;
69+ }
70+
71+ @ Override /** Return the object for the specified vertex index */
72+ public V getVertex (int index ) {
73+ return vertices .get (index );
74+ }
75+
76+ @ Override /** Return the index for the specified vertex object */
77+ public int getIndex (V v ) {
78+ return vertices .indexOf (v );
79+ }
80+
81+ @ Override /** Return the neighbors of the specified vertex */
82+ public List <Integer >getNeighbors (int index ) {
83+ List <Integer >result =new ArrayList <>();
84+ for (Edge e :neighbors .get (index )) {
85+ result .add (e .v );
86+ }
87+
88+ return result ;
89+ }
90+
91+ @ Override /** Return the degree for a spceified vertex */
92+ public int getDegree (int v ) {
93+ return neighbors .get (v ).size ();
94+ }
95+
96+ @ Override /** Print the edges */
97+ public void printEdges () {
98+ for (int u =0 ;u <neighbors .size ();u ++) {
99+ System .out .print (getVertex (u ) +" (" +u +"): " );
100+ for (Edge e :neighbors .get (u )) {
101+ System .out .print ("(" +getVertex (e .u ) +", " +
102+ getVertex (e .v ) +") " );
103+ }
104+ System .out .println ();
105+ }
106+ }
107+
108+ @ Override /** Clear the graph */
109+ public void clear () {
110+ vertices .clear ();
111+ neighbors .clear ();
112+ }
113+
114+ @ Override /** Add a vertex to the graph */
115+ public boolean addVertex (V vertex ) {
116+ if (!vertices .contains (vertex )) {
117+ vertices .add (vertex );
118+ neighbors .add (new ArrayList <Edge >());
119+ return true ;
120+ }
121+ return false ;
122+ }
123+
124+ /** Add an edge to the grpah */
125+ private 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 .v <0 ||e .v >getSize () -1 )
130+ throw new IllegalArgumentException ("No such index: " +e .v );
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+
170+ // Mark visited vertices
171+ boolean []isVisited =new boolean [vertices .size ()];
172+
173+ // Recursively search
174+ dfs (v ,parent ,searchOrder ,isVisited );
175+
176+ // Return a search
177+ return new Tree (v ,parent ,searchOrder );
178+ }
179+
180+ /** Recursive method for DFS search */
181+ private void dfs (int u ,int []parent ,
182+ List <Integer >searchOrder ,boolean []isVisited ) {
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 /** Obtain a BFS tree starting 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+
202+ LinkedList <Integer >queue =new LinkedList <>();
203+ boolean []isVisited =new boolean [vertices .size ()];
204+
205+ queue .offer (v );// Enqueue v
206+ isVisited [v ] =true ;// Mark it visited
207+
208+ while (!queue .isEmpty ()) {
209+ int u =queue .poll ();
210+ searchOrder .add (u );
211+ for (Edge e :neighbors .get (u )) {
212+ if (!isVisited [e .v ]) {
213+ queue .offer (e .v );
214+ parent [e .v ] =u ;
215+ isVisited [e .v ] =true ;
216+ }
217+ }
218+ }
219+
220+ return new Tree (v ,parent ,searchOrder );
221+ }
222+
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 of 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 root to vertex v */
269+ public void printPath (int index ) {
270+ List <V >path =getPath (index );
271+ System .out .print ("A path from " +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+
278+ /** Print the whole tree */
279+ public void printTree () {
280+ System .out .println ("Root is: " +vertices .get (root ));
281+ System .out .print ("Edges: " );
282+ for (int i =0 ;i <parent .length ;i ++) {
283+ if (parent [i ] != -1 ) {
284+ // Display an edge
285+ System .out .print ("(" +vertices .get (parent [i ]) +", " +
286+ vertices .get (i ) +") " );
287+ }
288+ }
289+ System .out .println ();
290+ }
291+ }
292+ }