DFS Algorithm

The Depth-First Search (DFS) Algorithm is a popular graph traversal technique used in computer science and mathematics for exploring and traversing tree or graph data structures. It starts at the root node or any arbitrary node and explores as far as possible along each branch before backtracking. The primary goal of the DFS algorithm is to visit all the nodes in a graph or tree, marking each visited node and keeping track of the traversed path. This algorithm is particularly useful in various applications such as network analysis, pathfinding, topological sorting, and solving puzzles like mazes. The DFS algorithm can be implemented using recursion or an explicit stack data structure. In the recursive approach, the algorithm calls itself for each unvisited adjacent node until it reaches a dead-end, at which point it backtracks to the previous node and continues the exploration. In the stack-based approach, the algorithm iteratively pushes the current node onto the stack, marks it as visited, and proceeds to the next unvisited adjacent node. When a dead-end is reached, the algorithm pops the top node off the stack and backtracks to explore other branches. The DFS algorithm has a time complexity of O(V + E), where V is the number of vertices and E is the number of edges in the graph, making it an efficient approach to traverse large graphs or trees.
/*
 * Copyright (c) 2017 Kotlin Algorithm Club
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.algorithmexamples.graphs

import com.algorithmexamples.datastructures.Stack

class DFS {
    companion object Implementations {
        fun iterative(graph: Graph,
                      preorder: ((Int) -> Unit)? = null,
                      postorder: ((Int) -> Unit)? = null) {
            val visited = IntArray(graph.V)
            val queue = Stack<Int>()
            for (i in 0 until graph.V) {
                if (visited[i] == 0) {
                    queue.push(i)
                    visited[i] = 1
                    while (!queue.isEmpty()) {
                        val v = queue.poll()
                        if (visited[v] == 1) {
                            visited[i] = 2
                            preorder?.invoke(i)
                            queue.push(v)
                            for (w in graph.adjacentVertices(v)) {
                                if (visited[w] == 0) {
                                    queue.push(w)
                                    visited[w] = 1
                                }
                            }
                        } else {
                            visited[i] = 3
                            postorder?.invoke(i)
                        }
                    }
                }
            }
        }

        fun recursive(graph: Graph,
                      preorder: ((Int) -> Unit)? = null,
                      postorder: ((Int) -> Unit)? = null) {
            val visited = BooleanArray(graph.V)
            for (i in 0..graph.V - 1) {
                if (!visited[i]) {
                    dfs(i, graph, visited, preorder, postorder)
                }
            }
        }

        private fun dfs(v: Int, graph: Graph, visited: BooleanArray,
                        preorder: ((Int) -> Unit)? = null,
                        postorder: ((Int) -> Unit)? = null) {
            visited[v] = true
            preorder?.invoke(v)
            for (w in graph.adjacentVertices(v)) {
                if (!visited[w]) {
                    dfs(w, graph, visited, preorder, postorder)
                }
            }
            postorder?.invoke(v)
        }
    }
}

LANGUAGE:

DARK MODE: