Kotlin Program to Implement Breadth-First Search (BFS)

Kotlin Program to Implement Breadth-First Search (BFS)

When it comes to exploring graphs, trees, or even grid-based structures, one of the most important algorithms to know is Breadth-First Search (BFS). Unlike Depth-First Search (DFS), which dives deep into a branch before backtracking, BFS explores all nodes level by level. This makes it ideal for finding the shortest path between nodes, searching through networks, or traversing data structures where distance or layers matter.

Pluralsight Logo
Accelerate your tech career
with hands-on learning.
Whether you're a tech newbie or a total pro,
get the skills and confidence to land your next move.
Start 10-Day Free Trial

BFS is widely used in computer science and programming because it ensures that all nodes at the same level are visited before moving deeper. It’s particularly helpful in real-world applications like social networks to find connections, in maps to find the shortest route, and in puzzles or games for optimal solutions. Learning BFS in Kotlin not only strengthens your grasp on queues and loops but also provides a foundation for solving many practical problems efficiently.

Program 1: BFS Using Queue on a Graph

This program demonstrates the standard BFS traversal on a graph represented by an adjacency list.

import java.util.LinkedList
import java.util.Queue

fun bfs(graph: Map<Int, List<Int>>, start: Int) {

    val visited = mutableSetOf<Int>()
    val queue: Queue<Int> = LinkedList()

    queue.add(start)
    visited.add(start)

    while (queue.isNotEmpty()) {

        val node = queue.poll()

        println(node)

        for (neighbor in graph[node] ?: emptyList()) {

            if (!visited.contains(neighbor)) {
                visited.add(neighbor)
                queue.add(neighbor)
            }

        }

    }

}

fun main() {

    val graph = mapOf(
        0 to listOf(1, 2),
        1 to listOf(0, 3, 4),
        2 to listOf(0, 4),
        3 to listOf(1, 5),
        4 to listOf(1, 2, 5),
        5 to listOf(3, 4)
    )

    println("BFS Traversal starting from node 0:")
    bfs(graph, 0)

}

In this program, a queue ensures that nodes are explored level by level. Beginners can see how BFS systematically visits neighbors, making it ideal for scenarios where the shortest path matters.

Program 2: BFS on a Binary Tree

BFS can also be applied to trees, often referred to as level-order traversal.

import java.util.LinkedList
import java.util.Queue

data class TreeNode(val value: Int, val left: TreeNode? = null, val right: TreeNode? = null)

fun bfsBinaryTree(root: TreeNode?) {

    if (root == null) return

    val queue: Queue<TreeNode> = LinkedList()
    queue.add(root)

    while (queue.isNotEmpty()) {

        val node = queue.poll()

        println(node.value)

        node.left?.let { queue.add(it) }
        node.right?.let { queue.add(it) }

    }

}

fun main() {

    val tree = TreeNode(1,
        TreeNode(2, TreeNode(4), TreeNode(5)),
        TreeNode(3, TreeNode(6), TreeNode(7))
    )

    println("BFS Traversal of Binary Tree:")

    bfsBinaryTree(tree)

}

This program shows how BFS can traverse a tree level by level. For beginners, it highlights how a queue can control the order of processing nodes effectively.

Program 3: BFS for Shortest Path in Unweighted Graph

BFS is useful for finding the shortest distance between nodes in an unweighted graph.

import java.util.LinkedList
import java.util.Queue

fun shortestPath(graph: Map<Int, List<Int>>, start: Int, target: Int): Int {

    val visited = mutableSetOf<Int>()
    val queue: Queue<Pair<Int, Int>> = LinkedList()

    queue.add(Pair(start, 0))
    visited.add(start)

    while (queue.isNotEmpty()) {

        val (node, distance) = queue.poll()

        if (node == target) return distance

        for (neighbor in graph[node] ?: emptyList()) {

            if (!visited.contains(neighbor)) {

                visited.add(neighbor)
                queue.add(Pair(neighbor, distance + 1))

            }

        }

    }

    return -1

}

fun main() {

    val graph = mapOf(
        0 to listOf(1, 2),
        1 to listOf(0, 3, 4),
        2 to listOf(0, 4),
        3 to listOf(1, 5),
        4 to listOf(1, 2, 5),
        5 to listOf(3, 4)
    )

    val distance = shortestPath(graph, 0, 5)

    println("Shortest path from 0 to 5: $distance")

}

Here, BFS guarantees the shortest path in an unweighted graph by exploring nodes layer by layer. Beginners can see BFS’s practical application in network and routing problems.

Program 4: BFS on a Grid (Maze Traversal)

BFS can also traverse 2D grids or mazes, finding the shortest route from a starting cell.

import java.util.LinkedList
import java.util.Queue

fun bfsGrid(grid: Array<IntArray>, startX: Int, startY: Int) {

    val rows = grid.size
    val cols = grid[0].size
    val visited = Array(rows) { BooleanArray(cols) }
    val directions = arrayOf(intArrayOf(1,0), intArrayOf(-1,0), intArrayOf(0,1), intArrayOf(0,-1))
    val queue: Queue<Pair<Int, Int>> = LinkedList()

    queue.add(Pair(startX, startY))
    visited[startX][startY] = true

    while (queue.isNotEmpty()) {

        val (x, y) = queue.poll()

        println("Visiting: ($x, $y)")

        for (dir in directions) {

            val newX = x + dir[0]
            val newY = y + dir[1]

            if (newX in 0 until rows && newY in 0 until cols &&
                !visited[newX][newY] && grid[newX][newY] == 1) {

                visited[newX][newY] = true
                queue.add(Pair(newX, newY))

            }

        }

    }

}

fun main() {

    val grid = arrayOf(
        intArrayOf(1, 1, 0, 0),
        intArrayOf(1, 1, 0, 1),
        intArrayOf(0, 0, 1, 1),
        intArrayOf(0, 1, 1, 0)
    )

    println("BFS Traversal on Grid:")
    bfsGrid(grid, 0, 0)

}

This program illustrates BFS exploring connected cells level by level. Beginners can relate it to solving maze or shortest path problems in games or simulations.

Program 5: BFS to Check Connectivity in a Graph

BFS can also be used to check if a graph is fully connected.

import java.util.LinkedList
import java.util.Queue

fun isConnected(graph: Map<Int, List<Int>>, start: Int): Boolean {

    val visited = mutableSetOf<Int>()
    val queue: Queue<Int> = LinkedList()

    queue.add(start)
    visited.add(start)

    while (queue.isNotEmpty()) {

        val node = queue.poll()

        for (neighbor in graph[node] ?: emptyList()) {

            if (!visited.contains(neighbor)) {
                visited.add(neighbor)
                queue.add(neighbor)
            }

        }

    }

    return visited.size == graph.size

}

fun main() {

    val graph = mapOf(
        0 to listOf(1, 2),
        1 to listOf(0, 3, 4),
        2 to listOf(0, 4),
        3 to listOf(1, 5),
        4 to listOf(1, 2, 5),
        5 to listOf(3, 4)
    )

    println("Graph is connected: ${isConnected(graph, 0)}")

}

BFS visits all reachable nodes, making it easy to check whether every node can be accessed from a starting point. Beginners can see BFS applied in practical scenarios like network validation.

Frequently Asked Questions (FAQ)

Q1: What is Breadth-First Search (BFS)?
BFS is a graph traversal algorithm that explores nodes level by level using a queue.

Q2: When should I use BFS?
BFS is useful when you want the shortest path, check connectivity, or explore a graph layer by layer.

Q3: How does BFS differ from DFS?
BFS explores all neighbors first (level by level), while DFS explores as deep as possible before backtracking.

Q4: Can BFS handle weighted graphs?
Standard BFS works for unweighted graphs; for weighted graphs, algorithms like Dijkstra are used.

Q5: What is the time complexity of BFS?
BFS has a time complexity of O(V + E), where V is the number of vertices and E is the number of edges.

Conclusion

Breadth-First Search is an essential algorithm for graph, tree, and grid traversal. In Kotlin, BFS can be implemented using queues, allowing systematic exploration of nodes or cells. By practicing BFS, beginners can strengthen their understanding of traversal strategies, queues, and problem-solving for shortest path or connectivity challenges. Mastering BFS opens the door to more advanced graph algorithms and real-world applications like routing, maze-solving, and social network analysis.

Scroll to Top