1
+ /**
2
+ * Represents a generic directed graph using an adjacency list.
3
+ *
4
+ * @param <T> The type of data stored in the vertices of the graph.
5
+ */
6
+ public class Graph <T > {
7
+ /**
8
+ * Represents the first adjacency list in the graph.
9
+ */
10
+ AdjList <T > firstList ;
11
+
12
+ /**
13
+ * The count of vertices in the graph.
14
+ */
15
+ int vertexCount ;
16
+
17
+ /**
18
+ * The count of edges in the graph.
19
+ */
20
+ int edgeCount ;
21
+
22
+ /**
23
+ * Represents the last adjacency list in the graph.
24
+ */
25
+ AdjList <T > lastList ;
26
+
27
+ /**
28
+ * Represents a node in the adjacency list of a directed graph.
29
+ *
30
+ * @param <T> The type of data stored in the vertex.
31
+ */
32
+ private class AdjList <T > {
33
+ /**
34
+ * Reference to the next adjacency list in the graph.
35
+ */
36
+ AdjList <T > nextList ;
37
+
38
+ /**
39
+ * The data stored in the vertex.
40
+ */
41
+ T data ;
42
+
43
+ /**
44
+ * The number of outgoing edges (outdegree) from this vertex.
45
+ */
46
+ int outdegree ;
47
+
48
+ /**
49
+ * Reference to the first member (edge) in the adjacency list.
50
+ */
51
+ Member <T > firstMember ;
52
+
53
+ /**
54
+ * Constructs an empty adjacency list node.
55
+ */
56
+ AdjList () {
57
+ }
58
+
59
+ /**
60
+ * Constructs an adjacency list node with the specified data.
61
+ *
62
+ * @param newVertex The data for the vertex.
63
+ */
64
+ AdjList (T newVertex ) {
65
+ data = newVertex ;
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Represents a member of an adjacency list in a graph.
71
+ *
72
+ * @param <T> The type of the adjacency vertex.
73
+ */
74
+ private class Member <T > {
75
+ /**
76
+ * The adjacent vertex connected by this member.
77
+ */
78
+ T adjVertex ;
79
+
80
+ /**
81
+ * The weight associated with the connection to the adjacent vertex.
82
+ */
83
+ int weight ;
84
+
85
+ /**
86
+ * The next member in the adjacency list.
87
+ */
88
+ Member <T > nextMember ;
89
+
90
+ /**
91
+ * Default constructor for the member.
92
+ */
93
+ Member () {
94
+ }
95
+
96
+ /**
97
+ * Parameterized constructor for the member.
98
+ *
99
+ * @param toV The adjacent vertex.
100
+ * @param weight The weight of the connection to the adjacent vertex.
101
+ */
102
+ Member (T toV , int weight ) {
103
+ adjVertex = toV ;
104
+ this .weight = weight ;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Inserts a new vertex into the graph.
110
+ *
111
+ * @param newVertex The new vertex to be inserted.
112
+ */
113
+ void insertVertex (T newVertex ) { // Exercise 1
114
+
115
+ // A temporary adjacency list representing the new vertex.
116
+ AdjList <T > temp = new AdjList <T >();
117
+
118
+ // Set the data of the temporary adjacency list to the new vertex.
119
+ temp .data = newVertex ;
120
+
121
+ if (vertexCount == 0 ) { //insert as the first vertex(root)
122
+ // TODO: add your code here
123
+ firstList = temp ; //intialize first
124
+ lastList = temp ; //initial last
125
+ } else { //insert at some children
126
+ // TODO: add your code here
127
+ lastList .nextList = temp ; //
128
+ lastList = temp ;
129
+ }
130
+ vertexCount ++;
131
+ }
132
+
133
+ /**
134
+ * Searches for an adjacency list in the graph containing the specified data.
135
+ *
136
+ * @param data The data to be searched for in the adjacency lists.
137
+ * @return The adjacency list containing the specified data, or null if not
138
+ * found.
139
+ */
140
+ AdjList <T > searchAdjList (T data ) { // Exercise 2
141
+
142
+ // The current adjacency list being examined, starting from the first adjacency
143
+ // list.
144
+ AdjList <T > current = firstList ;
145
+
146
+ while (current != null ) { //when there's still Adjlist
147
+ // TODO: add your code here
148
+ if (current .data == data ){
149
+ return current ;
150
+ }
151
+ else { //continue search
152
+ current = current .nextList ;
153
+ }
154
+ }
155
+ return null ;
156
+ }
157
+
158
+ /**
159
+ * Inserts a directed edge with a specified weight from one vertex to another in
160
+ * the graph.
161
+ *
162
+ * @param fromData The data of the vertex from which the edge starts.
163
+ * @param toData The data of the vertex to which the edge is directed.
164
+ * @param weight The weight of the edge.
165
+ */
166
+ void insertEdge (T fromData , T toData , int weight ) { // Exercise 3 (Assume that fromData and toData exist in the graph)
167
+ // The adjacency list corresponding to the vertex from which the edge starts.
168
+ AdjList <T > fromAdjList = searchAdjList (fromData );
169
+
170
+ // Creates a new member (edge) with the specified destination vertex and weight
171
+ Member <T > newMember = new Member <T >(toData , weight );
172
+
173
+ // TODO: add your code here
174
+ newMember .nextMember = fromAdjList .firstMember ; //connect newmember to firstlist of fromAdjlist(connect on the left of newmember)
175
+ fromAdjList .firstMember = newMember ; //connect fromAdjlist to newmember(connect on the right of newmember)
176
+ fromAdjList .outdegree ++;
177
+ edgeCount ++;
178
+ }
179
+
180
+ /**
181
+ * Deletes the directed edge from one vertex to another in the graph.
182
+ *
183
+ * @param fromData The data of the vertex from which the edge starts.
184
+ * @param toData The data of the vertex to which the edge is directed.
185
+ */
186
+ void deleteEdge (T fromData , T toData ) { // Exercise 4
187
+
188
+ // The adjacency list corresponding to the vertex from which the edge starts.
189
+ AdjList <T > fromAdjList = searchAdjList (fromData );
190
+
191
+ if (fromAdjList == null ) //No start node
192
+ return ;
193
+
194
+ if (fromAdjList .firstMember != null && toData .equals (fromAdjList .firstMember .adjVertex )) {
195
+ //Have first member, check if firstmember is what we want to delete)
196
+ // TODO: add your code here
197
+ fromAdjList .firstMember = fromAdjList .firstMember .nextMember ; //overpass the member toV
198
+ fromAdjList .outdegree --;
199
+ edgeCount --;
200
+ } else if (fromAdjList .firstMember != null && !toData .equals (fromAdjList .firstMember .adjVertex )) {
201
+ //have first member, if firstmemebr is not what we want to delete, then we continue shifting
202
+ Member <T > temp = fromAdjList .firstMember ;
203
+ while (temp != null && temp .nextMember != null ) {
204
+ // TODO: add your code here
205
+ if (temp .nextMember .adjVertex .equals (toData )){
206
+ temp .nextMember = temp .nextMember .nextMember ;
207
+ fromAdjList .outdegree --;
208
+ edgeCount --;
209
+ }
210
+ else { //continue shifting
211
+ temp = temp .nextMember ;
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Deletes a vertex from the graph, including all edges connected to it.
219
+ *
220
+ * @param vertex The data of the vertex to be deleted.
221
+ */
222
+ void deleteVertex (T vertex ) { // Exercise 5
223
+
224
+ // The current adjacency list being processed.
225
+ AdjList <T > currentAdjList = firstList ;
226
+
227
+ // The previous adjacency list before the current one.
228
+ AdjList <T > prevAdjList = firstList ;
229
+
230
+ //Not good structure
231
+ while (currentAdjList != null ) {
232
+ if (!currentAdjList .data .equals (vertex )) {
233
+ // TODO: add your code here
234
+ deleteEdge (currentAdjList .data , vertex );
235
+ prevAdjList = currentAdjList ;
236
+ currentAdjList = currentAdjList .nextList ;
237
+ } else {
238
+ if (currentAdjList == firstList ) { //delete first vertex
239
+ firstList = currentAdjList .nextList ;
240
+ } else if (currentAdjList == lastList ) { //delete last vertex
241
+ // TODO: add your code here
242
+ lastList = prevAdjList ;
243
+ lastList .nextList = null ;
244
+ } else { //delete any vertex
245
+ // TODO: add your code here
246
+ edgeCount -= currentAdjList .outdegree ;
247
+ vertexCount --;
248
+ prevAdjList .nextList = currentAdjList .nextList ;
249
+ currentAdjList = currentAdjList .nextList ;
250
+
251
+ }
252
+ }
253
+ }
254
+ // while (currentAdjList != null) {
255
+ // if (!currentAdjList.data.equals(vertex)) { //firstlist not equal to vertex ~ check for the edge we want to delete
256
+ // // TODO: add your code here
257
+ // deleteEdge(currentAdjList.data, vertex);
258
+ // } else { //if currentAdjList is the vertex we want to delete
259
+ // if (currentAdjList == firstList) { //delete first vertex
260
+ // firstList = currentAdjList.nextList;
261
+ // edgeCount -= currentAdjList.outdegree; //delete edge
262
+ // vertexCount--;
263
+ // } else if (currentAdjList == lastList) { //delete last vertex
264
+ // // TODO: add your code here
265
+ // lastList = prevAdjList;
266
+ // lastList.nextList = null;
267
+ // edgeCount -= currentAdjList.outdegree; //delete edge
268
+ // vertexCount--;
269
+ // } else { //delete any vertex
270
+ // // TODO: add your code here
271
+ // edgeCount -= currentAdjList.outdegree; //delete edge
272
+ // vertexCount--;
273
+ // prevAdjList.nextList = currentAdjList.nextList; //overpass
274
+ // currentAdjList = currentAdjList.nextList;
275
+ // }
276
+ //
277
+ // }
278
+ // prevAdjList = currentAdjList; //overpass graph
279
+ // currentAdjList = currentAdjList.nextList;
280
+ // }
281
+ }
282
+
283
+ /**
284
+ * Prints the graph by displaying each vertex along with its connected vertices <br>
285
+ * and edge weights. The format of the output is as follows: <br>
286
+ * Vertex1 --> ConnectedVertex1,Weight1 --> ConnectedVertex2,Weight2 --> ... <br>
287
+ * Vertex2 --> ... <br>
288
+ * ... <br>
289
+ * The graph's vertex and edge counts are also displayed at the end.
290
+ */
291
+ void print () {
292
+ AdjList <T > currentList = firstList ;
293
+ while (currentList != null ) {
294
+ System .out .print (currentList .data );
295
+ Member <T > cMem = currentList .firstMember ;
296
+ while (cMem != null ) {
297
+ System .out .print ("-->" + cMem .adjVertex );
298
+ System .out .print ("," + cMem .weight );
299
+ cMem = cMem .nextMember ;
300
+ }
301
+ System .out .println ("" );
302
+ currentList = currentList .nextList ;
303
+
304
+ }
305
+ System .out .println ("The graph consists of " + vertexCount + " vertices " + "and " + edgeCount + " edges." );
306
+ }
307
+ }
0 commit comments