Skip to content
Back to skills

Algo Bfs Dfs

ASecurity

Graph Traversals: BFS and DFS with Matplotlib

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aipythongonodetesting

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add Pavel-Kravchenko/Bioinformatics --skill algo-bfs-dfs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Algo Bfs Dfs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Algo Bfs Dfs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/pavel-kravchenko-algo-bfs-dfs/badge)](https://www.skillsdirectory.com/skills/pavel-kravchenko-algo-bfs-dfs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: algo-bfs-dfs
description: "Graph Traversals: BFS and DFS with Matplotlib"
tool_type: python
primary_tool: Matplotlib
---

#  Graph Traversals: BFS and DFS

## Breadth-First Search (BFS)

BFS explores vertices level by level, using a **queue** (FIFO).

```python
       A           Level 0: A
      /|\
     B C D         Level 1: B, C, D
    /|   |
   E F   G         Level 2: E, F, G
```

**Use cases:**
- Shortest path in unweighted graphs
- Finding all nodes within k hops (network neighborhood)
- Level-order traversal

```python
def bfs(graph, start):
    """
    Breadth-First Search from start vertex.
    Returns: (visited order, distances from start)
    Time: O(V + E), Space: O(V)
    """
    visited = set([start])
    queue = deque([start])
    order = []
    distances = {start: 0}

    while queue:
        vertex = queue.popleft()
        order.append(vertex)

        for neighbor in graph.neighbors(vertex):
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
                distances[neighbor] = distances[vertex] + 1

    return order, distances

# Build a sample PPI network
ppi = Graph()
edges = [
    ('TP53', 'MDM2'), ('TP53', 'BRCA1'), ('TP53', 'ATM'),
    ('MDM2', 'RB1'), ('BRCA1', 'CHEK2'), ('ATM', 'CHEK2'),
    ('RB1', 'E2F1'), ('CHEK2', 'CDC25A')
]
for u, v in edges:
    ppi.add_edge(u, v)

order, distances = bfs(ppi, 'TP53')
print("BFS traversal from TP53:", order)
print("\nDistances from TP53:")
for gene, dist in sorted(distances.items(), key=lambda x: x[1]):
    print(f"  {gene}: {dist} hops")
```

```python
def find_neighbors_within_k(graph, start, k):
    """Find all vertices within k edges of start (network neighborhood)."""
    _, distances = bfs(graph, start)
    return [v for v, d in distances.items() if d <= k and v != start]

# Find genes within 2 hops of TP53
neighborhood = find_neighbors_within_k(ppi, 'TP53', 2)
print(f"Genes within 2 hops of TP53: {neighborhood}")
```

## Depth-First Search (DFS)

DFS explores as far as possible along each branch before backtracking, using a **stack** (LIFO) or recursion.

**Use cases:**
- Cycle detection
- Topological sorting
- Finding connected components
- Path finding (any path, not necessarily shortest)

```python
def dfs_iterative(graph, start):
    """
    Depth-First Search using explicit stack.
    Time: O(V + E), Space: O(V)
    """
    visited = set()
    stack = [start]
    order = []

    while stack:
        vertex = stack.pop()
        if vertex not in visited:
            visited.add(vertex)
            order.append(vertex)
            # Add neighbors in reverse for consistent ordering
            for neighbor in sorted(graph.neighbors(vertex), reverse=True):
                if neighbor not in visited:
                    stack.append(neighbor)

    return order

def dfs_recursive(graph, start, visited=None):
    """DFS using recursion."""
    if visited is None:
        visited = set()

    visited.add(start)
    order = [start]

    for neighbor in sorted(graph.neighbors(start)):
        if neighbor not in visited:
            order.extend(dfs_recursive(graph, neighbor, visited))

    return order

print("DFS iterative from TP53:", dfs_iterative(ppi, 'TP53'))
print("DFS recursive from TP53:", dfs_recursive(ppi, 'TP53'))
```

## Finding Connected Components

In biological networks, connected components represent functional modules or pathways.

```python
def find_connected_components(graph):
    """Find all connected components using DFS."""
    visited = set()
    components = []

    for vertex in graph.vertices():
        if vertex not in visited:
            # Start new component
            component = []
            stack = [vertex]

            while stack:
                v = stack.pop()
                if v not in visited:
                    visited.add(v)
                    component.append(v)
                    for neighbor in graph.neighbors(v):
                        if neighbor not in visited:
                            stack.append(neighbor)

            components.append(component)

    return components

# Add a disconnected component
ppi.add_edge('KRAS', 'BRAF')
ppi.add_edge('BRAF', 'MEK1')

components = find_connected_components(ppi)
print(f"Found {len(components)} connected components:")
for i, comp in enumerate(components, 1):
    print(f"  Component {i}: {comp}")
```

## BFS vs DFS Comparison

| Feature | BFS | DFS |
|---------|-----|-----|
| Data structure | Queue | Stack/Recursion |
| Explores | Level by level | Branch by branch |
| Shortest path | ✅ Yes (unweighted) | ❌ No |
| Memory | O(width) | O(depth) |
| Cycle detection | Possible | Natural fit |
| Topological sort | No | Yes |

## 🧬 Exercise 1: Shortest Path Between Genes

Implement a function to find the shortest path between two genes using BFS.

```python
def shortest_path(graph, start, end):
    """Find shortest path from start to end using BFS."""
    if start == end:
        return [start]

    visited = {start}
    queue = deque([(start, [start])])

    while queue:
        vertex, path = queue.popleft()

        for neighbor in graph.neighbors(vertex):
            if neighbor == end:
                return path + [neighbor]
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, path + [neighbor]))

    return None  # No path exists

# Test: Find path from E2F1 to ATM
path = shortest_path(ppi, 'E2F1', 'ATM')
print(f"Shortest path E2F1 → ATM: {' → '.join(path)}")
```

## 🧬 Exercise 2: Cycle Detection

Implement cycle detection using DFS. In biological networks, cycles can indicate feedback loops.

```python
def has_cycle(graph):
    """Detect if undirected graph has a cycle using DFS."""
    visited = set()

    def dfs(vertex, parent):
        visited.add(vertex)
        for neighbor in graph.neighbors(vertex):
            if neighbor not in visited:
                if dfs(neighbor, vertex):
                    return True
            elif neighbor != parent:
                return True  # Found cycle
        return False

    for v in graph.vertices():
        if v not in visited:
            if dfs(v, None):
                return True
    return False

# Add a cycle
ppi.add_edge('ATM', 'BRCA1')  # Creates TP53-ATM-BRCA1-TP53 cycle
print(f"Network has cycle: {has_cycle(ppi)}")
```


## Summary

✅ BFS uses a queue, explores level-by-level, finds shortest paths
✅ DFS uses a stack/recursion, explores depth-first, good for cycles
✅ Both have O(V + E) time complexity
✅ Connected components reveal network modules

**Next:** [03_dijkstra.ipynb](03_dijkstra.ipynb) - Shortest paths with weighted edges

## Pitfalls

- **Coordinate systems**: BED uses 0-based half-open; VCF/GFF use 1-based inclusive — mixing them causes off-by-one errors
- **Batch effects**: Always check for batch confounding before interpreting biological signal
- **Multiple testing**: Apply FDR correction (Benjamini-Hochberg) when testing thousands of features simultaneously

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…