Tarjan: Difference between revisions

Content added Content deleted
m (→‎{{header|Perl}}: fixed Perl code)
(+python)
Line 487: Line 487:
{4,5}
{4,5}
{8}
{8}
</pre>

=={{header|Python}}==
<lang python>from collections import defaultdict

def from_edges(edges):
'''translate list of edges to list of nodes'''

class Node:
def __init__(self):
# root is one of:
# None: not yet visited
# -1: already processed
# non-negative integer: what Wikipedia pseudo code calls 'lowlink'
self.root = None
self.succ = []

nodes = defaultdict(Node)
for v,w in edges:
nodes[v].succ.append(nodes[w])

for i,v in nodes.items(): # name the nodes for final output
v.id = i

return nodes.values()

def trajan(V):
def strongconnect(v, S=[]):
v.root = pos = len(S)
S.append(v)

for w in v.succ:
if w.root is None: # not yet visited
yield from strongconnect(w)

if w.root >= 0: # still on stack
v.root = min(v.root, w.root)

if v.root == pos: # v is the root, return everything above
res, S[pos:] = S[pos:], []
for w in res:
w.root = -1
yield [r.id for r in res]

for v in V:
if v.root is None:
yield from strongconnect(v)


tables = [ # table 1
[(1,2), (3,1), (3,6), (6,7), (7,6), (2,3), (4,2),
(4,3), (4,5), (5,6), (5,4), (8,5), (8,7), (8,6)],

# table 2
[('A', 'B'), ('B', 'C'), ('C', 'A'), ('A', 'Other')]]

for table in (tables):
for g in trajan(from_edges(table)):
print(g)
print()</lang>
{{out}}
<pre>[6, 7]
[1, 2, 3]
[4, 5]
[8]

['Other']
['A', 'B', 'C']
</pre>
</pre>