Repository: networkx/networkx

Issue:
all_node_cuts returns incorrect cuts
The function `all_node_cuts` returns node cut-sets for the K2 (complete graph with two nodes), but there exist no.

### Current Behavior

Consider the following graph, consisting of two nodes connected by an edge:
```python
graph = nx.Graph()
graph.add_edge(1,2)
list(all_node_cuts(graph)
>>> [{1}, {2}]
```
This graph has no node cut-sets because removing any vertex does not increase the number of connected components

### Expected Behavior

Return no node cut-sets:
```python
graph = nx.Graph()
graph.add_edge(1,2)
list(all_node_cuts(graph)
>>> []
```

### Steps to Reproduce

The above example

### Environment

Python version: 3.10.10
NetworkX version: 2.6.3



Discussion:
I think this issue has to do with complete graphs in general, because for a complete graph with `n` nodes, the connectivity is `n-1` which is the size of every node cut-set.

_Node cut-set of an undirected graph G is the set of nodes, that if removed, would break G into two or more connected components._

For a K-N graph, we will have to remove n-1 nodes that will break the graph into two components - one with a single node and another with no nodes.

If we assume an empty graph to be a component by itself, then perhaps the output of `all_node_cuts` is valid, else maybe an exception can be raised whenever a complete graph is passed in.
TLDR; Issue #3025 points out a few bugs which were fixed in #3039 They left the complete graph case, but it seems  thatis not handled correctly.

Looking through the blame history of this function, it seems that bug reports such as #1875 have been fixed by adding extra code to handle those cases rather than fixing the underlying algorithm. Special code for e.g. cycles was also added but has since been removed without removing the code for complete graphs. I'm not sure why this approach was taken. Was the underlying algorithm investigated and found to be unable to handle those cases?  How do we know the underlying algorithm is correct?  I've been playing with it and it seems to work fine. 

The tests use `node_connnectivity` to give the size of the minimal cutset. The doc_string for `node_connectivity` mentions that the connectivity is the number of nodes that need to be removed so that the graph is disconnected **or the trivial graph** (trivial graph is one node, no edges). So, I believe the author considered a node cut-set to be the nodes which when removed leave a disconnected or trivial graph. 

By the definitions of node cut or vertex cut that I have found, it only is a cut if the resulting graph is disconnected. That is different from what is implemented here **I think**. 

But, are there graphs that are not complete graphs that have "no node cut-set". That is, there is no set of nodes which when removed leave the graph disconnected?  I don't think so... because if you consider an edge that isn't present in the graph, then removing all but the two nodes on either side of the missing edge will leave the two nodes -- a disconnected graph. I conclude that the only case where we might result in the trivial graph is if we start with a complete graph. 

The [wikipedia article on connectivity](https://en.wikipedia.org/wiki/Connectivity_(graph_theory)) states that "In particular, a complete graph with n vertices, denoted Kn, has no vertex cuts at all, but the vertex-connectivity is n − 1."

So I am left thinking that the original implementation on this function was correct, and the addition of specialized code to handle complete graphs was added (incorrectly) to produce "cuts" which lead to trivial graphs rather than disconnected graphs. That is, the added code made the node_connectivity equal to the size of the node cut-set. That trait is true for all graph except for complete graphs.

OK... enough of this train of thought writing. :} 
I think we should remove the code that handles complete graphs specially and fix the tests to check for equality of node_connectivity with the length of the cut sets unless the graph is a complete graph.  

Thoughts?
I too read a couple of articles yesterday that discussed cut sets with regard to complete graphs. (refer [CMU lecture notes](https://www.math.cmu.edu/~af1p/Teaching/GT/CH3.pdf), [Wolfram MathWorld](https://mathworld.wolfram.com/VertexCut.html)).

All sources said that complete graphs have no vertex cut, even though the vertex-connectivity is n − 1.

I think we should remove the code that handles the case of complete graphs. The test cases should check that in case of complete graphs, `list(all_node_cuts(KN_graph)` should be empty and of size node_connectivity in other cases.
I agree. Make the code return an empty set when the input is a complete graph. I think this just means deleting the special case handling code, but we better check that. :)
And let's change the current tests for complete graphs and change them to check the empty cut return value while also checking that node_connectivity is n-1 in that case. 

Resolving patch:
diff --git a/networkx/algorithms/connectivity/kcutsets.py b/networkx/algorithms/connectivity/kcutsets.py
--- a/networkx/algorithms/connectivity/kcutsets.py
+++ b/networkx/algorithms/connectivity/kcutsets.py
@@ -92,10 +92,11 @@ def all_node_cuts(G, k=None, flow_func=None):
 
     # Address some corner cases first.
     # For complete Graphs
+
     if nx.density(G) == 1:
-        for cut_set in combinations(G, len(G) - 1):
-            yield set(cut_set)
+        yield from ()
         return
+
     # Initialize data structures.
     # Keep track of the cuts already computed so we do not repeat them.
     seen = []
@@ -129,7 +130,7 @@ def all_node_cuts(G, k=None, flow_func=None):
     for x in X:
         # step 3: Compute local connectivity flow of x with all other
         # non adjacent nodes in G
-        non_adjacent = set(G) - X - set(G[x])
+        non_adjacent = set(G) - {x} - set(G[x])
         for v in non_adjacent:
             # step 4: compute maximum flow in an Even-Tarjan reduction H of G
             # and step 5: build the associated residual network R


Test patch:
diff --git a/networkx/algorithms/connectivity/tests/test_kcutsets.py b/networkx/algorithms/connectivity/tests/test_kcutsets.py
--- a/networkx/algorithms/connectivity/tests/test_kcutsets.py
+++ b/networkx/algorithms/connectivity/tests/test_kcutsets.py
@@ -259,8 +259,15 @@ def test_cycle_graph():
 
 def test_complete_graph():
     G = nx.complete_graph(5)
-    solution = [{0, 1, 2, 3}, {0, 1, 2, 4}, {0, 1, 3, 4}, {0, 2, 3, 4}, {1, 2, 3, 4}]
-    cuts = list(nx.all_node_cuts(G))
-    assert len(solution) == len(cuts)
-    for cut in cuts:
-        assert cut in solution
+    assert nx.node_connectivity(G) == 4
+    assert list(nx.all_node_cuts(G)) == []
+
+
+def test_all_node_cuts_simple_case():
+    G = nx.complete_graph(5)
+    G.remove_edges_from([(0, 1), (3, 4)])
+    expected = [{0, 1, 2}, {2, 3, 4}]
+    actual = list(nx.all_node_cuts(G))
+    assert len(actual) == len(expected)
+    for cut in actual:
+        assert cut in expected