@@ -530,6 +530,52 @@ def _strongly_connected_components_kosaraju_adjacency_list(graph):
530
530
_strongly_connected_components_kosaraju_adjacency_matrix = \
531
531
_strongly_connected_components_kosaraju_adjacency_list
532
532
533
+ def _tarjan_dfs (u , graph , index , stack , indices , low_links , on_stacks , components ):
534
+ indices [u ] = index [0 ]
535
+ low_links [u ] = index [0 ]
536
+ index [0 ] += 1
537
+ stack .append (u )
538
+ on_stacks [u ] = True
539
+
540
+ for node in graph .neighbors (u ):
541
+ v = node .name
542
+ if indices [v ] == - 1 :
543
+ _tarjan_dfs (v , graph , index , stack , indices , low_links , on_stacks , components )
544
+ low_links [u ] = min (low_links [u ], low_links [v ])
545
+ elif on_stacks [v ]:
546
+ low_links [u ] = min (low_links [u ], low_links [v ])
547
+
548
+ if low_links [u ] == indices [u ]:
549
+ component = set ()
550
+ while stack :
551
+ w = stack .pop ()
552
+ on_stacks [w ] = False
553
+ component .add (w )
554
+ if w == u :
555
+ break
556
+ components .append (component )
557
+
558
+ def _strongly_connected_components_tarjan_adjacency_list (graph ):
559
+ index = [0 ] # mutable object
560
+ stack = Stack ([])
561
+ indices , low_links , on_stacks = {}, {}, {}
562
+
563
+ for u in graph .vertices :
564
+ indices [u ] = - 1
565
+ low_links [u ] = - 1
566
+ on_stacks [u ] = False
567
+
568
+ components = []
569
+
570
+ for u in graph .vertices :
571
+ if indices [u ] == - 1 :
572
+ _tarjan_dfs (u , graph , index , stack , indices , low_links , on_stacks , components )
573
+
574
+ return components
575
+
576
+ _strongly_connected_components_tarjan_adjacency_matrix = \
577
+ _strongly_connected_components_tarjan_adjacency_list
578
+
533
579
def strongly_connected_components (graph , algorithm , ** kwargs ):
534
580
"""
535
581
Computes strongly connected components for the given
@@ -548,6 +594,7 @@ def strongly_connected_components(graph, algorithm, **kwargs):
548
594
supported,
549
595
550
596
'kosaraju' -> Kosaraju's algorithm as given in [1].
597
+ 'tarjan' -> Tarjan's algorithm as given in [2].
551
598
backend: pydatastructs.Backend
552
599
The backend to be used.
553
600
Optional, by default, the best available
@@ -577,6 +624,7 @@ def strongly_connected_components(graph, algorithm, **kwargs):
577
624
==========
578
625
579
626
.. [1] https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
627
+ .. [2] https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
580
628
581
629
"""
582
630
raise_if_backend_is_not_python (
0 commit comments