@@ -106,6 +106,133 @@ class DirectedGraph:
106
106
def out_degree(self, u):
107
107
return len(self.graph[u])
108
108
109
+ def topological_sort(self, s = -2):
110
+ stack = []
111
+ visited = []
112
+ if s == -2:
113
+ s = list(self.graph.keys())[0]
114
+ stack.append(s)
115
+ visited.append(s)
116
+ ss = s
117
+ sorted_nodes = []
118
+
119
+ while True:
120
+ # check if there is any non isolated nodes
121
+ if len(self.graph[s]) != 0:
122
+ ss = s
123
+ for __ in self.graph[s]:
124
+ if visited.count(__[1]) < 1:
125
+ stack.append(__[1])
126
+ visited.append(__[1])
127
+ ss =__[1]
128
+ break
129
+
130
+ # check if all the children are visited
131
+ if s == ss :
132
+ sorted_nodes.append(stack.pop())
133
+ if len(stack) != 0:
134
+ s = stack[len(stack) - 1]
135
+ else:
136
+ s = ss
137
+
138
+ # check if se have reached the starting point
139
+ if len(stack) == 0:
140
+ return sorted_nodes
141
+
142
+ def cycle_nodes(self):
143
+ stack = []
144
+ visited = []
145
+ s = list(self.graph.keys())[0]
146
+ stack.append(s)
147
+ visited.append(s)
148
+ parent = -2
149
+ indirect_parents = []
150
+ ss = s
151
+ anticipating_nodes = set()
152
+
153
+ while True:
154
+ # check if there is any non isolated nodes
155
+ if len(self.graph[s]) != 0:
156
+ ss = s
157
+ for __ in self.graph[s]:
158
+ if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
159
+ l = len(stack) - 1
160
+ while True and l >= 0:
161
+ if stack[l] == __[1]:
162
+ anticipating_nodes.add(__[1])
163
+ break
164
+ else:
165
+ anticipating_nodes.add(stack[l])
166
+ l -= 1
167
+ if visited.count(__[1]) < 1:
168
+ stack.append(__[1])
169
+ visited.append(__[1])
170
+ ss =__[1]
171
+ break
172
+
173
+ # check if all the children are visited
174
+ if s == ss :
175
+ stack.pop()
176
+ on_the_way_back = True
177
+ if len(stack) != 0:
178
+ s = stack[len(stack) - 1]
179
+ else:
180
+ on_the_way_back = False
181
+ indirect_parents.append(parent)
182
+ parent = s
183
+ s = ss
184
+
185
+ # check if se have reached the starting point
186
+ if len(stack) == 0:
187
+ return list(anticipating_nodes)
188
+
189
+ def has_cycle(self):
190
+ stack = []
191
+ visited = []
192
+ s = list(self.graph.keys())[0]
193
+ stack.append(s)
194
+ visited.append(s)
195
+ parent = -2
196
+ indirect_parents = []
197
+ ss = s
198
+ anticipating_nodes = set()
199
+
200
+ while True:
201
+ # check if there is any non isolated nodes
202
+ if len(self.graph[s]) != 0:
203
+ ss = s
204
+ for __ in self.graph[s]:
205
+ if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
206
+ l = len(stack) - 1
207
+ while True and l >= 0:
208
+ if stack[l] == __[1]:
209
+ anticipating_nodes.add(__[1])
210
+ break
211
+ else:
212
+ return True
213
+ anticipating_nodes.add(stack[l])
214
+ l -= 1
215
+ if visited.count(__[1]) < 1:
216
+ stack.append(__[1])
217
+ visited.append(__[1])
218
+ ss =__[1]
219
+ break
220
+
221
+ # check if all the children are visited
222
+ if s == ss :
223
+ stack.pop()
224
+ on_the_way_back = True
225
+ if len(stack) != 0:
226
+ s = stack[len(stack) - 1]
227
+ else:
228
+ on_the_way_back = False
229
+ indirect_parents.append(parent)
230
+ parent = s
231
+ s = ss
232
+
233
+ # check if se have reached the starting point
234
+ if len(stack) == 0:
235
+ return False
109
236
110
237
class Graph:
111
238
def __init__(self):
@@ -214,3 +341,98 @@ class Graph:
214
341
return visited
215
342
def degree(self, u):
216
343
return len(self.graph[u])
344
+
345
+ def cycle_nodes(self):
346
+ stack = []
347
+ visited = []
348
+ s = list(self.graph.keys())[0]
349
+ stack.append(s)
350
+ visited.append(s)
351
+ parent = -2
352
+ indirect_parents = []
353
+ ss = s
354
+ anticipating_nodes = set()
355
+
356
+ while True:
357
+ # check if there is any non isolated nodes
358
+ if len(self.graph[s]) != 0:
359
+ ss = s
360
+ for __ in self.graph[s]:
361
+ if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
362
+ l = len(stack) - 1
363
+ while True and l >= 0:
364
+ if stack[l] == __[1]:
365
+ anticipating_nodes.add(__[1])
366
+ break
367
+ else:
368
+ anticipating_nodes.add(stack[l])
369
+ l -= 1
370
+ if visited.count(__[1]) < 1:
371
+ stack.append(__[1])
372
+ visited.append(__[1])
373
+ ss =__[1]
374
+ break
375
+
376
+ # check if all the children are visited
377
+ if s == ss :
378
+ stack.pop()
379
+ on_the_way_back = True
380
+ if len(stack) != 0:
381
+ s = stack[len(stack) - 1]
382
+ else:
383
+ on_the_way_back = False
384
+ indirect_parents.append(parent)
385
+ parent = s
386
+ s = ss
387
+
388
+ # check if se have reached the starting point
389
+ if len(stack) == 0:
390
+ return list(anticipating_nodes)
391
+
392
+ def has_cycle(self):
393
+ stack = []
394
+ visited = []
395
+ s = list(self.graph.keys())[0]
396
+ stack.append(s)
397
+ visited.append(s)
398
+ parent = -2
399
+ indirect_parents = []
400
+ ss = s
401
+ anticipating_nodes = set()
402
+
403
+ while True:
404
+ # check if there is any non isolated nodes
405
+ if len(self.graph[s]) != 0:
406
+ ss = s
407
+ for __ in self.graph[s]:
408
+ if visited.count(__[1]) > 0 and __[1] != parent and indirect_parents.count(__[1]) > 0 and not on_the_way_back:
409
+ l = len(stack) - 1
410
+ while True and l >= 0:
411
+ if stack[l] == __[1]:
412
+ anticipating_nodes.add(__[1])
413
+ break
414
+ else:
415
+ return True
416
+ anticipating_nodes.add(stack[l])
417
+ l -= 1
418
+ if visited.count(__[1]) < 1:
419
+ stack.append(__[1])
420
+ visited.append(__[1])
421
+ ss =__[1]
422
+ break
423
+
424
+ # check if all the children are visited
425
+ if s == ss :
426
+ stack.pop()
427
+ on_the_way_back = True
428
+ if len(stack) != 0:
429
+ s = stack[len(stack) - 1]
430
+ else:
431
+ on_the_way_back = False
432
+ indirect_parents.append(parent)
433
+ parent = s
434
+ s = ss
435
+
436
+ # check if se have reached the starting point
437
+ if len(stack) == 0:
438
+ return False
0 commit comments