Visit every vertex of a small undirected graph in BFS order from a starting vertex. Uses an explicit FIFO queue and a visited hash to avoid re-visiting.

Algorithm

Basic Implementation

basic.sh
#!/usr/bin/env bash
set -euo pipefail
declare -A adj
adj[1]="2 3"
adj[2]="1 4"
adj[3]="1 4"
adj[4]="2 3 5"
adj[5]="4 6"
adj[6]="5"
start=1
declare -A visited
visited[$start]=1
queue=("$start")
order=()
head=0
while [ "$head" -lt "${#queue[@]}" ]; do
	v=${queue[head]}
	head=$((head + 1))
	order+=("$v")
	read -ra neighbours <<< "${adj[$v]}"
	i=0
	while [ "$i" -lt "${#neighbours[@]}" ]; do
		nb=${neighbours[i]}
		if [ -z "${visited[$nb]+_}" ]; then
			visited[$nb]=1
			queue+=("$nb")
		fi
		i=$((i + 1))
	done
done
printf '['
sep=''
for v in "${order[@]}"; do
	printf '%s%d' "$sep" "$v"
	sep=', '
done
printf ']\n'

BFS uses a queue, so it visits the start vertex, then its neighbours, then the next layer.

Step 1 - Start at 1

The queue starts with [1] and visited starts with {1}.

BFS start state: queue [1], visited {1}.1#123456

Step 2 - Visit the first layer

After processing 1, neighbours 2 and 3 are marked and queued.

Queue after visiting 1: [2, 3].1#12queued3queued456

Step 3 - Deterministic visit order

With insertion-ordered neighbours, BFS visits [1, 2, 3, 4, 5, 6].

Final BFS visit order from start 1.1#12#23#34#45#56#6

Complexity

  • Time: O(V + E)
  • Space: O(V) for the queue and visited hash

Implementation notes

  • Bash: declare -A adj stores adjacency lists as space-separated strings keyed by vertex; read -ra neighbours <<< "${adj[$v]}" splits each list into a positional array per pop without spawning a subshell.
  • The queue is an indexed array with a moving head cursor instead of unset-based dequeue, mirroring the stack lesson's cursor pattern.
  • visited is a separate declare -A hash so the +_ parameter expansion can test for set/unset without confusing zero-valued keys.
  • The replay reports each pop frame with the enqueued frontier so the viewer follows the BFS layer order.
queue and visited set Initialise `queue=(start)` and `visited[start]=1`. Pop the front, record it, then enqueue every unvisited neighbour while marking it visited.
layer order Because the queue is FIFO and a node is marked visited at enqueue time, BFS visits nodes in layer order from the start.