Repository: networkx/networkx

Issue:
bug report - BFS_Tree function
The source code, only generates list of edges of the bfs tree, from which the tree will be created.
therefore the case of tree with one-node only is missing. so if i run:
G = nx.Graph()
G.add_node(0)
print len(bfs_tree(G,0))

i get: 0. which is wrong.
please fix it,
Barak.



Discussion:
How about we just change bfs_tree() (and dfs_tree()) to 

```
def bfs_tree(G, source):
    """Return directed tree of breadth-first-search from source."""
    G = nx.DiGraph()
    G.add_node(source)
    G.add_edges_from(bfs_edges(G,source))
    return G
```

seems ok...

On Wed, Sep 26, 2012 at 4:39 PM, Aric Hagberg notifications@github.comwrote:

> How about we just change bfs_tree() (and dfs_tree()) to
> 
> def bfs_tree(G, source):
>     """Return directed tree of breadth-first-search from source."""
>     G = nx.DiGraph()
>     G.add_node(source)
>     G.add_edges_from(bfs_edges(G,source))
>     return G
> 
>  —
> Reply to this email directly or view it on GitHubhttps://github.com/networkx/networkx/issues/772#issuecomment-8892040.

Since there we have the possibility to set source=None for the DFS algorithms, we need to add all isolated vertices separately, or they'll be omitted.

Yes for the DFS algorithms that is true (the bfs_edges() implementation doesn't work the same way).
The simplest solution for dfs_tree() might be

```
def dfs_tree(G, source):                                                        
    T = nx.DiGraph()                                                            
    if source is None:                                                          
        T.add_nodes_from(G)                                                     
    else                                                                        
        T.add_node(source)                                                      
    T.add_edges_from(dfs_edges(G,source))                                       
    return T 
```

In this case of source=None this might not return a tree (a forest instead)


Resolving patch:
diff --git a/networkx/algorithms/traversal/breadth_first_search.py b/networkx/algorithms/traversal/breadth_first_search.py
--- a/networkx/algorithms/traversal/breadth_first_search.py
+++ b/networkx/algorithms/traversal/breadth_first_search.py
@@ -30,11 +30,12 @@ def bfs_edges(G,source):
         except StopIteration:
             stack.pop(0)
 
-
 def bfs_tree(G, source):
     """Return directed tree of breadth-first-search from source."""
-    return nx.DiGraph(bfs_edges(G,source))
-
+    T = nx.DiGraph()
+    T.add_node(source)
+    T.add_edges_from(bfs_edges(G,source))
+    return T
 
 def bfs_predecessors(G, source):
     """Return dictionary of predecessors in breadth-first-search from source."""
@@ -47,6 +48,3 @@ def bfs_successors(G, source):
     for s,t in bfs_edges(G,source):
         d[s].append(t)
     return dict(d)
-
-
-
diff --git a/networkx/algorithms/traversal/depth_first_search.py b/networkx/algorithms/traversal/depth_first_search.py
--- a/networkx/algorithms/traversal/depth_first_search.py
+++ b/networkx/algorithms/traversal/depth_first_search.py
@@ -1,6 +1,6 @@
 """
 ==================
-Depth-first search 
+Depth-first search
 ==================
 
 Basic algorithms for depth-first searching.
@@ -45,11 +45,15 @@ def dfs_edges(G,source=None):
             except StopIteration:
                 stack.pop()
 
-
-def dfs_tree(G, source=None):
+def dfs_tree(G, source):
     """Return directed tree of depth-first-search from source."""
-    return nx.DiGraph(dfs_edges(G,source=source))
-
+    T = nx.DiGraph()
+    if source is None:
+        T.add_nodes_from(G)
+    else:
+        T.add_node(source)
+    T.add_edges_from(dfs_edges(G,source))
+    return T
 
 def dfs_predecessors(G, source=None):
     """Return dictionary of predecessors in depth-first-search from source."""
@@ -65,7 +69,7 @@ def dfs_successors(G, source=None):
 
 
 def dfs_postorder_nodes(G,source=None):
-    """Produce nodes in a depth-first-search post-ordering starting 
+    """Produce nodes in a depth-first-search post-ordering starting
     from source.
     """
     post=(v for u,v,d in nx.dfs_labeled_edges(G,source=source)
@@ -77,7 +81,7 @@ def dfs_postorder_nodes(G,source=None):
 
 def dfs_preorder_nodes(G,source=None):
     """Produce nodes in a depth-first-search pre-ordering starting at source."""
-    pre=(v for u,v,d in nx.dfs_labeled_edges(G,source=source) 
+    pre=(v for u,v,d in nx.dfs_labeled_edges(G,source=source)
          if d['dir']=='forward')
     # chain source to beginning of pre-ordering
 #    return chain([source],pre)
@@ -118,4 +122,3 @@ def dfs_labeled_edges(G,source=None):
                 if stack:
                     yield stack[-1][0],parent,{'dir':'reverse'}
         yield start,start,{'dir':'reverse'}
-


Test patch:
diff --git a/networkx/algorithms/traversal/tests/test_bfs.py b/networkx/algorithms/traversal/tests/test_bfs.py
--- a/networkx/algorithms/traversal/tests/test_bfs.py
+++ b/networkx/algorithms/traversal/tests/test_bfs.py
@@ -27,3 +27,10 @@ def test_bfs_edges(self):
         edges=nx.bfs_edges(self.G,source=0)
         assert_equal(list(edges),[(0, 1), (1, 2), (1, 3), (2, 4)])
 
+    def test_bfs_tree_isolates(self):
+        G = nx.Graph()
+        G.add_node(1)
+        G.add_node(2)
+        T=nx.bfs_tree(G,source=1)
+        assert_equal(sorted(T.nodes()),[1])
+        assert_equal(sorted(T.edges()),[])
diff --git a/networkx/algorithms/traversal/tests/test_dfs.py b/networkx/algorithms/traversal/tests/test_dfs.py
--- a/networkx/algorithms/traversal/tests/test_dfs.py
+++ b/networkx/algorithms/traversal/tests/test_dfs.py
@@ -55,4 +55,14 @@ def test_dfs_labeled_disconnected_edges(self):
         edges=list(nx.dfs_labeled_edges(self.D))
         forward=[(u,v) for (u,v,d) in edges if d['dir']=='forward']
         assert_equal(forward,[(0, 0), (0, 1), (2, 2), (2, 3)])
-    
+
+    def test_dfs_tree_isolates(self):
+        G = nx.Graph()
+        G.add_node(1)
+        G.add_node(2)
+        T=nx.dfs_tree(G,source=1)
+        assert_equal(sorted(T.nodes()),[1])
+        assert_equal(sorted(T.edges()),[])
+        T=nx.dfs_tree(G,source=None)
+        assert_equal(sorted(T.nodes()),[1, 2])
+        assert_equal(sorted(T.edges()),[])