Repository: networkx/networkx

Issue:
Discrepancy in 'strongly_connected_components_recursive' for Detecting SCCs
Hey NetworkX team! 👋
### Description:
While attempting to identify strongly connected components (SCCs) of a graph using the `strongly_connected_components`, `strongly_connected_components_recursive`, and `kosaraju_strongly_connected_components` methods provided by `networkx`, inconsistent SCCs were observed. Notably, the `strongly_connected_components_recursive` method identified node `8` as a separate SCC, while the other two methods included node `8` in a larger SCC.\
For context, I've minimized my original, much larger graph to a smaller version to isolate and highlight the issue. 


### Observed Behavior:
- Using `strongly_connected_components`: [{0, 2, 3, 5, 6, 7, 8, 10}, {1}, {4}, {9}]
- Using `strongly_connected_components_recursive`: [{8}, {0, 2, 3, 5, 6, 7, 10}, {1}, {4}, {9}]
- Using `kosaraju_strongly_connected_components`: [{1}, {0, 2, 3, 5, 6, 7, 8, 10}, {9}, {4}]

### Expected Behavior:
All three methods should produce consistent SCCs. Node `8` should be part of the larger SCC `{0, 2, 3, 5, 6, 7, 8, 10}` based on the provided edges.

### Steps to Reproduce:
1. Create a directed graph with the provided nodes and edges.
2. Compute SCCs using the `strongly_connected_components`, `strongly_connected_components_recursive`, and `kosaraju_strongly_connected_components` methods.

### Environment:
Python version: 3.8.10
NetworkX version: 3.1

```python
import networkx as nx
from matplotlib import pyplot as plt


class Graph:
    def __init__(self):
        self.graph = nx.DiGraph()

    def add_nodes(self, nodes):
        for node in nodes:
            self.graph.add_node(node)

    def add_edges(self, edges):
        for edge in edges:
            self.graph.add_edge(edge[0], edge[1])

    def compute_scc(self):
        """Compute the result using three functions and print them"""
        result1 = list(nx.strongly_connected_components(self.graph))
        result2 = list(nx.strongly_connected_components_recursive(self.graph))
        result3 = list(nx.kosaraju_strongly_connected_components(self.graph))

        print("Using strongly_connected_components:", result1)
        print("Using strongly_connected_components_recursive:", result2)
        print("Using kosaraju_strongly_connected_components:", result3)

if __name__ == "__main__":
    nodes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    edges = [
        (0, 2), (0, 8), (0, 10), (2, 3), (3, 10),
        (3, 0), (4, 6), (4, 1), (5, 6), (5, 7),
        (6, 2), (6, 5), (7, 10), (8, 7), (9, 8),
        (10, 6)
    ]

    graph_instance = Graph()
    graph_instance.add_nodes(nodes)
    graph_instance.add_edges(edges)
    graph_instance.compute_scc()



Discussion:
Hi @iany0 ! I am not on the team of NetworkX, but I am also interested in the robustness of NetworkX.
I investigated your graph data and found that `node: 8` should not be in an isolated strongest component.
I also find the issue of the code is here in lines 246 to 249 of [strongly_connected.py](https://github.com/networkx/networkx/blob/main/networkx/algorithms/components/strongly_connected.py), and another issue of this code is that `cnt` should not be independent for different visitings.
These codes should be:
```Python
    def visit(v, cnt):
        root[v] = cnt[0]
        visited[v] = cnt[0]
        cnt[0] += 1
        stack.append(v)
        for w in G[v]:
            if w not in visited:
                yield from visit(w, cnt)
                root[v] = min(root[v], root[w])
            elif w not in component:
                root[v] = min(root[v], visited[w])
        print(v, root[v], visited[v])
        if root[v] == visited[v]:
            component[v] = root[v]
            tmpc = {v}  # hold nodes in this component
            while stack[-1] != v:
                w = stack.pop()
                component[w] = root[v]
                tmpc.add(w)
            stack.remove(v)
            yield tmpc

    visited = {}
    component = {}
    root = {}
    cnt = [0]
    stack = []
    for source in G:
        if source not in visited:
            yield from visit(source, cnt)
```

This change can fix the inconsistency and return the correct result for `strongly_connected_components_recursive`
I will also try to commit my fix for the issue.

Cheers for your findings!


Best regards,
Joye
Thanks for the bug report and and thanks for the fix. :)
This problem has been around for a long long time, and shows how little use the recursive version of the function has received. I can verify that the bug is present -- users should not trust results from the recursive version of the code until it is fixed. 

See #6898

Resolving patch:
diff --git a/networkx/algorithms/components/strongly_connected.py b/networkx/algorithms/components/strongly_connected.py
--- a/networkx/algorithms/components/strongly_connected.py
+++ b/networkx/algorithms/components/strongly_connected.py
@@ -178,6 +178,11 @@ def kosaraju_strongly_connected_components(G, source=None):
 def strongly_connected_components_recursive(G):
     """Generate nodes in strongly connected components of graph.
 
+    .. deprecated:: 3.2
+
+       This function is deprecated and will be removed in a future version of
+       NetworkX. Use `strongly_connected_components` instead.
+
     Recursive version of algorithm.
 
     Parameters
@@ -236,35 +241,18 @@ def strongly_connected_components_recursive(G):
        Information Processing Letters 49(1): 9-14, (1994)..
 
     """
+    import warnings
+
+    warnings.warn(
+        (
+            "\n\nstrongly_connected_components_recursive is deprecated and will be\n"
+            "removed in the future. Use strongly_connected_components instead."
+        ),
+        category=DeprecationWarning,
+        stacklevel=2,
+    )
 
-    def visit(v, cnt):
-        root[v] = cnt
-        visited[v] = cnt
-        cnt += 1
-        stack.append(v)
-        for w in G[v]:
-            if w not in visited:
-                yield from visit(w, cnt)
-            if w not in component:
-                root[v] = min(root[v], root[w])
-        if root[v] == visited[v]:
-            component[v] = root[v]
-            tmpc = {v}  # hold nodes in this component
-            while stack[-1] != v:
-                w = stack.pop()
-                component[w] = root[v]
-                tmpc.add(w)
-            stack.remove(v)
-            yield tmpc
-
-    visited = {}
-    component = {}
-    root = {}
-    cnt = 0
-    stack = []
-    for source in G:
-        if source not in visited:
-            yield from visit(source, cnt)
+    yield from strongly_connected_components(G)
 
 
 @not_implemented_for("undirected")
diff --git a/networkx/conftest.py b/networkx/conftest.py
--- a/networkx/conftest.py
+++ b/networkx/conftest.py
@@ -117,6 +117,11 @@ def set_warnings():
     warnings.filterwarnings(
         "ignore", category=DeprecationWarning, message="function `join` is deprecated"
     )
+    warnings.filterwarnings(
+        "ignore",
+        category=DeprecationWarning,
+        message="\n\nstrongly_connected_components_recursive",
+    )
 
 
 @pytest.fixture(autouse=True)


Test patch:
diff --git a/networkx/algorithms/components/tests/test_strongly_connected.py b/networkx/algorithms/components/tests/test_strongly_connected.py
--- a/networkx/algorithms/components/tests/test_strongly_connected.py
+++ b/networkx/algorithms/components/tests/test_strongly_connected.py
@@ -63,7 +63,8 @@ def test_tarjan(self):
     def test_tarjan_recursive(self):
         scc = nx.strongly_connected_components_recursive
         for G, C in self.gc:
-            assert {frozenset(g) for g in scc(G)} == C
+            with pytest.deprecated_call():
+                assert {frozenset(g) for g in scc(G)} == C
 
     def test_kosaraju(self):
         scc = nx.kosaraju_strongly_connected_components
@@ -168,7 +169,8 @@ def test_null_graph(self):
         G = nx.DiGraph()
         assert list(nx.strongly_connected_components(G)) == []
         assert list(nx.kosaraju_strongly_connected_components(G)) == []
-        assert list(nx.strongly_connected_components_recursive(G)) == []
+        with pytest.deprecated_call():
+            assert list(nx.strongly_connected_components_recursive(G)) == []
         assert len(nx.condensation(G)) == 0
         pytest.raises(
             nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph()
@@ -181,7 +183,8 @@ def test_connected_raise(self):
         with pytest.raises(NetworkXNotImplemented):
             next(nx.kosaraju_strongly_connected_components(G))
         with pytest.raises(NetworkXNotImplemented):
-            next(nx.strongly_connected_components_recursive(G))
+            with pytest.deprecated_call():
+                next(nx.strongly_connected_components_recursive(G))
         pytest.raises(NetworkXNotImplemented, nx.is_strongly_connected, G)
         pytest.raises(
             nx.NetworkXPointlessConcept, nx.is_strongly_connected, nx.DiGraph()
@@ -191,7 +194,6 @@ def test_connected_raise(self):
     strong_cc_methods = (
         nx.strongly_connected_components,
         nx.kosaraju_strongly_connected_components,
-        nx.strongly_connected_components_recursive,
     )
 
     @pytest.mark.parametrize("get_components", strong_cc_methods)