BFS

Complete

Summary

Breadth first search(BFS)

Time complexity

  • using an adjacency list
  • same as DFS
  • average case: - every time a vertex is dequeued, check all neighbours

Concept

Algorithm

  1. enqueue every neighbour into a queue
  2. while the queue is not empty, dequeue the first vertex and enqueue its neighbours
java
List<List<Integer>> AL; // O(V+E) only using adjacency list
List<Boolean> visited = new ArrayList<>(Collections.nCopies(V, false)); // keep track of visited vertices

void bfs(int s) {
	visited.set(s, true);
	Queue<Integer> q = new LinkedList<>();
	q.add(s); // enqueue the source
	
	while (!q.isEmpty()) {
		int u = q.poll(); // dequeue vertex
		// do something
	
		for (int v : AL.get(u)) // for all neighbouring vertices
			if (!visited.get(v)) {
				visited.set(v, true);
				q.add(v); // enqueue neighbours if not yet visited
			}
	}
}

all the neighbours are enqueued before moving on to the sibling, the queue can grow exponentially on graphs with large branching factor

BFS spanning tree

01142731041425386119121315
curr | queue
_    | [ 0 ]
0    | [ 1, 2 ]
1    | [ 2, 3 ]      // 0 was already visited
2    | [ 3, 4 ]      // 0 was already visited
3    | [ 4 ]         // 1, 2 were already visited
4    | [ ]

BFS on disconnected graphs

  • still
  • same as DFS
java
List<List<Integer>> al; // O(V+E) only using adjacency list
List<Boolean> visited;  // keep track of visited vertices

void bfs(int u) {
	visited.set(u, true);
	Queue<Integer> q = new LinkedList<>();
	q.add(u); // enqueue the source

	while (!q.isEmpty()) {
		int curr = q.poll(); // dequeue vertex
		// do something

		for (int v : al.get(curr)) // for all neighbouring vertices
			if (!visited.get(v)) {
				visited.set(v, true);
				q.add(v); // enqueue neighbours if not yet visited
			}
	}
}

for (int i = 0; i < visited.length(); i++)
	if (!visited.get(i))
		bfs(i); // if there are any vertices not connected to the first vertex, this will find and call BFS on them

Application

Leetcode: Binary Tree Right Side View

  • get rightmost node at each level
  • BFS such that rightmost is last to be visited
java
public List<Integer> rightSideView(TreeNode root) {
	LinkedList<Integer> out = new LinkedList<>();

	Queue<TreeNode> q = new LinkedList<>();
	Queue<Integer> h = new LinkedList<>();
	if (root != null) {
		q.add(root);
		h.add(0);
	}

	while (!q.isEmpty()) {
		TreeNode curr = q.poll();
		int height = h.poll();
		
		// add left first then right, so that right most will be visited last
		if (curr.left != null) {
			q.add(curr.left);
			h.add(height + 1);
		}
		if (curr.right != null) {
			q.add(curr.right);
			h.add(height + 1);
		}

		if (out.size() <= height)
			out.add(curr.val);
		else
			out.set(height, curr.val);
	}

	return out;
}