๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/์•Œ๊ณ ๋ฆฌ์ฆ˜

๊ทธ๋ž˜ํ”„ - ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ (DFS, Depth-First Search)

interfacer_han 2024. 9. 23. 20:27

#1 ๊ทธ๋ž˜ํ”„์˜ ํƒ์ƒ‰

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „

์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „. ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์˜ˆ์‹œ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰( - ๅ„ชๅ…ˆๆŽข็ดข, ์˜์–ด: depth-first search, DFS)์€ ๋งน๋ชฉ์  ํƒ์ƒ‰๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜๋กœ ํƒ์ƒ‰ํŠธ๋ฆฌ์˜ ์ตœ๊ทผ์— ์ฒจ๊ฐ€

ko.wikipedia.org

๊ทธ๋ž˜ํ”„์˜ ๊ฐ ์ •์ ์„ ํ•œ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ณด์ž. ๊ทธ ๋ฐฉ๋ฌธ์˜ ๋ฐฉ๋ฒ•์—๋Š” ํฌ๊ฒŒ 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ํ•˜๋‚˜๋Š” ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์ด๋‹ค. ๋˜ ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์ด๋‹ค. ๋ณธ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰๋ฒ•์„ ๋‹ค๋ฃฌ๋‹ค. (๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์— ๋Œ€ํ•ด์„œ๋Š” ์ด ๊ฒŒ์‹œ๊ธ€์—์„œ ๋‹ค๋ฃฌ๋‹ค)
 

#2 ์•Œ๊ณ ๋ฆฌ์ฆ˜

https://commons.wikimedia.org/wiki/File:Depth-first-tree.svg

์›๋ž˜๋ผ๋ฉด ์ˆœ์„œ๋„๋ฅผ ํ†ตํ•ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์†Œ๊ฐœํ•˜๊ณ  ์ฝ”๋“œ๋กœ ๋„˜์–ด๊ฐ€๋Š” ํŽธ์ด ์ดํ•ดํ•˜๊ธฐ ์ข‹์ง€๋งŒ, ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ถ€ํ„ฐ ๋ณด๋Š” ๊ฒŒ ์˜คํžˆ๋ ค ์ดํ•ด๊ฐ€ ๋” ๋น ๋ฅด๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋‹ค๋งŒ, ์ธ์ ‘ ๋ฐฐ์—ด (Adjacency Array)์˜ ์ง€์‹์— ๋Œ€ํ•ด์„œ๋Š” ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์ „์ œ ํ•˜๋‹ค. ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•  ์ธ์ ‘ ๋ฐฐ์—ด์€ ์ด ๊ฒŒ์‹œ๊ธ€์— ์žˆ๋‹ค (๊ฐ€์ค‘์น˜๊ฐ€ ์—†๋Š” ๋ฌดํ–ฅ ๊ทธ๋ž˜ํ”„).

๋Œ€์‹  ์™œ '๊นŠ์ด ์šฐ์„ ' ํƒ์ƒ‰์ด๋ผ๋Š” ์ด๋ฆ„์ด ๋ถ™์—ˆ๋Š”์ง€๋Š” ์„ค๋ช…ํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋‹ค. ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์€ ๋‹ค๋ฅธ ๋ง๋กœ '์ฒซ๋ฒˆ์งธ ์ž์‹ ์šฐ์„ ' ํƒ์ƒ‰์ด๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ทธ๋ž˜ํ”„๋Š” ๊นŠ์ด์˜ ๋†’๋‚ฎ์ด๊ฐ€ ์œ„ ๊ทธ๋ž˜ํ”„์ฒ˜๋Ÿผ y์ถ•๊ณผ ํ‰ํ–‰ํ•˜๊ฒŒ ๊ทธ๋ ค์ง„๋‹ค. ๋”ฐ๋ผ์„œ '์ฒซ๋ฒˆ์งธ ์ž์‹ ์šฐ์„ '์œผ๋กœ ํƒ์ƒ‰ํ•œ๋‹ค๋Š” ๋ง์€, 2 โ†’ 3 โ†’ 4 โ†’ 5 โ†’ 6 โ†’ 7 โ†’ 8์™€ ๊ฐ™์€ ์‹์œผ๋กœ ํƒ์ƒ‰ํ•œ๋‹ค๋Š” ๋ง์ด ๋œ๋‹ค. ์ด ํƒ์ƒ‰์€ y์ถ•(๋†’์ด)๋ฅผ ์šฐ์„ ํ•ด ์ด๋™ํ•˜๋Š” ๋ชจ์–‘์ด ๋œ๋‹ค (x์ถ• ์ด๋™์€ y์ถ• ํƒ์ƒ‰์ด ์ข…๋ฃŒ๋œ ํ›„์— ์‹œํ–‰๋œ๋‹ค. ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์•„๋‹Œ ๊ฒƒ์ด๋‹ค). ๊ทธ๋ž˜์„œ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์ด๋ผ ๋ถ€๋ฅธ๋‹ค.
 

#3 ์ฝ”๋“œ - ์ฝ”ํ‹€๋ฆฐ

#3-1 ๊ธฐ๋ณธ ์ฝ”๋“œ

fun main() {
    // (1) listOfAdjacencyArray[n]์ด ๊ฐ€์ง€๋Š” ์˜๋ฏธ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค (์„ค๋ช… ์ฐธ์กฐ)
    val listOfAdjacencyArray = listOf(
        arrayOf(1, 2),
        arrayOf(0, 3, 4),
        arrayOf(0, 4),
        arrayOf(1),
        arrayOf(1, 2)
    )

    // (2) visited๋Š” ๋ฐฉ๋ฌธ์ด ์™„๋ฃŒ๋œ ์ •์ ๋“ค์„ ๊ธฐ๋กํ•˜๋Š” Set(์ง‘ํ•ฉ)์ด๋‹ค
    val visited = mutableSetOf<Int>()
    dfs(listOfAdjacencyArray, 0, visited)  // 0๋ฒˆ ์ •์ (vertex)์—์„œ ํƒ์ƒ‰ ์‹œ์ž‘
}

fun dfs(listOfAdjacencyArray: List<Array<Int>>, vertex: Int, visited: MutableSet<Int>) {
    // (3) ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์ ์„ visited์— ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฐฉ๋ฌธํ•ด์„œ ์ง„ํ–‰ํ•  ์ผ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์—ฌ๊ธฐ์„  doSomethingFunction()์œผ๋กœ ํ‘œํ˜„ํ–ˆ๋‹ค
    visited.add(vertex)
//  doSomethingFunction(vertex)
    println("Visit complete: $vertex")

    // (4) ์ •์ ์˜ ์ด์›ƒ ์ •์ ๋งˆ๋‹ค (5)์„ ์ˆ˜ํ–‰
    for (neighborVertex in listOfAdjacencyArray[vertex]) {
        // (5) visited ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด, ์ด์›ƒ ์ •์ ์„ ์žฌ๊ท€ ํ˜ธ์ถœํ•œ๋‹ค
        if (neighborVertex !in visited) {
            dfs(listOfAdjacencyArray, neighborVertex, visited)
        }
    }
}

(1) listOfAdjacencyArray[n]์ด ๊ฐ€์ง€๋Š” ์˜๋ฏธ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค
์ •์ ์— ๋ถ€์—ฌ๋œ ๋ฒˆํ˜ธ๊ฐ€ 0 ~ N์ผ ๋•Œ, listOfAdjacencyArray[n]์€ n๋ฒˆ ์ •์ ์— ์—ฐ๊ฒฐ๋œ ์ด์›ƒ(neighbor) ์ •์ ๋“ค์˜ ๋ฐฐ์—ด์„ ์˜๋ฏธํ•œ๋‹ค.

(2) visited๋Š” ๋ฐฉ๋ฌธ์ด ์™„๋ฃŒ๋œ ์ •์ ๋“ค์„ ๊ธฐ๋กํ•˜๋Š” Set(์ง‘ํ•ฉ)์ด๋‹ค
bfs์™€ ๋‹ฌ๋ฆฌ visited๊ฐ€ ๋ฐ–์— ๋‚˜์™€ ์žˆ๋‹ค. dfs์˜ ๊ตฌ์กฐ(์žฌ๊ท€ ํ˜ธ์ถœ) ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๋‹ค

(3) ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์ ์„ visited์— ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฐฉ๋ฌธ...
bfs์— ๋Œ€ํ•ด ๋‹ค๋ฃฌ ์ด ๊ฒŒ์‹œ๊ธ€๊ณผ ๋‹ฌ๋ฆฌ, Setํ˜• ๋ณ€์ˆ˜ ์ด๋ฆ„์„ visited๋ผ๊ณ  ๋‘์—ˆ๋‹ค. bfs์—์„œ์™€ ๋‹ฌ๋ฆฌ ๋ณธ ๊ฒŒ์‹œ๊ธ€(dfs)์—์„œ๋Š”, ์–ด๋–ค ์ •์ ์„ Set์— ๋„ฃ์Œ(add())๊ณผ ๋™์‹œ์— ํ•ด๋‹น ์ •์ ์— '๋ฐฉ๋ฌธ'ํ•œ ๊ฒƒ์œผ๋กœ ์ทจ๊ธ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

(4) ์ •์ ์˜ ์ด์›ƒ ์ •์ ๋งˆ๋‹ค (5)์„ ์ˆ˜ํ–‰
listOfAdjacencyArray[n]์€ ๋ฐฉ๊ธˆ ๋ฐฉ๋ฌธ ์™„๋ฃŒํ•œ ์ •์  n์— ์—ฐ๊ฒฐ๋œ ์ด์›ƒ ์ •์ ๋“ค์˜ ๋ฐฐ์—ด์ด๋‹ค. ์ด ๋ฐฐ์—ด์˜ ์š”์†Œ๋งˆ๋‹ค (5)์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

(5) visited ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด, ์ด์›ƒ ์ •์ ์„ ์žฌ๊ท€ ํ˜ธ์ถœํ•œ๋‹ค
์žฌ๊ท€ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์žฌ๊ท€ ํ˜ธ์ถœ์€ ์Šคํƒ ๊ตฌ์กฐ๋ฅผ ์ด๋ฃฌ๋‹ค. ์ฆ‰, ๊ฐ€์žฅ ๋Šฆ๊ฒŒ(์ตœ๊ทผ์—) ์žฌ๊ท€ ํ˜ธ์ถœ๋œ dfs()๊ฐ€ ๋จผ์ € ์ฒ˜๋ฆฌ๋œ๋‹ค (ํ›„์ž… ์„ ์ถœ). #2์—์„œ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์„ '์ฒซ๋ฒˆ์งธ ์ž์‹ ์šฐ์„ ' ํƒ์ƒ‰์ด๋ผ๊ณ  ๋งํ•œ ์ด์œ ๋‹ค. ๊ฐ ์žฌ๊ท€ ํ˜ธ์ถœ์€ listOfAdjacencyArray[vertex]์˜ ์ฒซ๋ฒˆ์งธ ์›์†Œ ์ฆ‰ listOfAdjacencyArray[vertex][0]๋ถ€ํ„ฐ ์ˆ˜ํ–‰๋œ๋‹ค. ๋˜, ํ•ด๋‹น ์žฌ๊ท€ ํ˜ธ์ถœ์—์„œ ์—ฐ์‡„์ ์œผ๋กœ ๋ฐœ์ƒํ•  ์žฌ๊ท€ ํ˜ธ์ถœ ๋˜ํ•œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ธ์ ‘ ๋ฐฐ์—ด์— ์ ํžŒ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ถ€ํ„ฐ ์ˆ˜ํ–‰๋  ๊ฒƒ์ด๋‹ค.

#3-2 ์ œ๋„ค๋ฆญ์„ ์ด์šฉํ•œ ์ฝ”๋“œ

import kotlin.collections.HashMap

fun main() {
    // (1) mapOfAdjacencyArray[n]์ด ๊ฐ€์ง€๋Š” ์˜๋ฏธ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค (์„ค๋ช… ์ฐธ์กฐ)
    val mapOfAdjacencyArray = HashMap<String, Array<String>>()
    mapOfAdjacencyArray["๊ฐ•์•„์ง€"] = arrayOf("๊ณ ์–‘์ด", "์‚ฌ์Šด")
    mapOfAdjacencyArray["๊ณ ์–‘์ด"] = arrayOf("๊ฐ•์•„์ง€", "์ฝ”๋ฟ”์†Œ", "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด")
    mapOfAdjacencyArray["์‚ฌ์Šด"] = arrayOf("๊ฐ•์•„์ง€", "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด")
    mapOfAdjacencyArray["์ฝ”๋ฟ”์†Œ"] = arrayOf("๊ณ ์–‘์ด")
    mapOfAdjacencyArray["ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด"] = arrayOf("๊ณ ์–‘์ด", "์‚ฌ์Šด")

    // (2) visited๋Š” ๋ฐฉ๋ฌธ์ด ์™„๋ฃŒ๋œ ์ •์ ๋“ค์„ ๊ธฐ๋กํ•˜๋Š” Set(์ง‘ํ•ฉ)์ด๋‹ค
    val visited = mutableSetOf<String>()
    dfs(mapOfAdjacencyArray, "๊ฐ•์•„์ง€", visited)  // "๊ฐ•์•„์ง€" ์ •์ (vertex)์—์„œ ํƒ์ƒ‰ ์‹œ์ž‘
}

fun <T> dfs(mapOfAdjacencyArray: Map<T, Array<T>>, vertex: T, visited: MutableSet<T>) {
    // (3) ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์ ์„ visited์— ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฐฉ๋ฌธํ•ด์„œ ์ง„ํ–‰ํ•  ์ผ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์—ฌ๊ธฐ์„  doSomethingFunction()์œผ๋กœ ํ‘œํ˜„ํ–ˆ๋‹ค
    visited.add(vertex)
//  doSomethingFunction(vertex)
    println("Visit complete: $vertex")

    // (4) ์ •์ ์˜ ์ด์›ƒ ์ •์ ๋งˆ๋‹ค (5)์„ ์ˆ˜ํ–‰
    for (neighborVertex in mapOfAdjacencyArray[vertex]!!) {
        // (5) visited ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด, ์ด์›ƒ ์ •์ ์„ ์žฌ๊ท€ ํ˜ธ์ถœํ•œ๋‹ค
        if (neighborVertex !in visited) {
            dfs(mapOfAdjacencyArray, neighborVertex, visited)
        }
    }
}

์ง€๊ธˆ๊นŒ์ง€ ์ •์ ์„ ํŽธ์˜์ƒ Intํ˜•์ด๋ผ๊ณ ๋งŒ ๋‹ค๋ค˜์ง€๋งŒ, ์ •์ ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ธฐ์ค€์ด ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐํ˜•์ผ ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๋„ค๋ฆญ์„ ์ด์šฉํ•ด ๋ฆฌํŒฉํ† ๋งํ•œ ์ฝ”๋“œ๋‹ค. listOfAdjacencyArray๊ฐ€ mapOfAdjacencyArray๋กœ ๋ฐ”๋€ ๊ฒƒ์—๋„ ์ฃผ๋ชฉํ•˜์ž. listOfAdjacencyArray์˜ index๋Š” ๋ฐ˜๋“œ์‹œ Int์—ฌ์•ผ ํ•œ๋‹ค๋Š” ์ œ์•ฝ ์กฐ๊ฑด์ด ์žˆ๊ธฐ์— ์ด index์˜ ์—ญํ• ์„, mapOfAdjacencyArray์˜ key๊ฐ€ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค.
 

#3-3 ๋ฐฑํŠธ๋ž˜ํ‚น (Backtracking)

๊ฐœ๋…
๋ฐฑํŠธ๋ž˜ํ‚น(Backtracking)์ด๋ž€ ๋ฐฑํŠธ๋ž˜ํ‚น์€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํƒ์ƒ‰ํ•˜๋˜, ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ์ •๋‹ต์ด ๋  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ๋Š” ๋นจ๋ฆฌ ํฌ๊ธฐ(๊ฐ€์ง€์น˜๊ธฐ) ํ•˜๊ณ  ๋Œ์•„์˜ค๋Š” ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค. ๊ฐ€๋ น, ์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” "๊ฐ•์•„์ง€"๋กœ๋ถ€ํ„ฐ "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด"๊นŒ์ง€ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ๋กœ์˜ ์ˆ˜๋ฅผ ์ฐพ๋Š” ์ฝ”๋“œ๋‹ค (๋‹จ, ํ•œ ๋ฒˆ ๋ฐฉ๋ฌธํ•œ ์ •์ ์€ ๋‹ค์‹œ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์—†์Œ).
 
์ฝ”๋“œ์™€ ์„ค๋ช…

// ๊ฒฝ๋กœ ํƒ์ƒ‰ ๋ฌธ์ œ๋ผ๋Š” ๊ฐ€์ • ํ•˜์˜ ์ฝ”๋“œ์ด๋ฏ€๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋“ค
val start = "๊ฐ•์•„์ง€"
val goal = "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด"
val path = mutableListOf<String>()

fun main() {
    // (1) mapOfAdjacencyArray[n]์ด ๊ฐ€์ง€๋Š” ์˜๋ฏธ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค (์„ค๋ช… ์ฐธ์กฐ)
    val mapOfAdjacencyArray = HashMap<String, Array<String>>()
    mapOfAdjacencyArray["๊ฐ•์•„์ง€"] = arrayOf("๊ณ ์–‘์ด", "์‚ฌ์Šด")
    mapOfAdjacencyArray["๊ณ ์–‘์ด"] = arrayOf("๊ฐ•์•„์ง€", "์ฝ”๋ฟ”์†Œ", "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด")
    mapOfAdjacencyArray["์‚ฌ์Šด"] = arrayOf("๊ฐ•์•„์ง€", "ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด")
    mapOfAdjacencyArray["์ฝ”๋ฟ”์†Œ"] = arrayOf("๊ณ ์–‘์ด")
    mapOfAdjacencyArray["ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด"] = arrayOf("๊ณ ์–‘์ด", "์‚ฌ์Šด")

    // (2) visited๋Š” ๋ฐฉ๋ฌธ์ด ์™„๋ฃŒ๋œ ์ •์ ๋“ค์„ ๊ธฐ๋กํ•˜๋Š” Set(์ง‘ํ•ฉ)์ด๋‹ค
    val visited = mutableSetOf<String>()

    println("๋ชจ๋“  ๊ฒฝ๋กœ:") // ๊ฒฝ๋กœ ํƒ์ƒ‰ ๋ฌธ์ œ๋ผ๋Š” ๊ฐ€์ • ํ•˜์˜ ์ฝ”๋“œ์ด๋ฏ€๋กœ.
    dfs(mapOfAdjacencyArray, start, visited)  // start ์ •์ (vertex)์—์„œ ํƒ์ƒ‰ ์‹œ์ž‘
}

fun <T> dfs(mapOfAdjacencyArray: Map<T, Array<T>>, vertex: T, visited: MutableSet<T>) {
    // (3) ๋งค๊ฐœ๋ณ€์ˆ˜ ์ •์ ์„ visited์— ์ถ”๊ฐ€ํ•˜๊ณ , ๋ฐฉ๋ฌธํ•ด์„œ ์ง„ํ–‰ํ•  ์ผ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ์—ฌ๊ธฐ์„  doSomethingFunction()์œผ๋กœ ํ‘œํ˜„ํ–ˆ๋‹ค
    visited.add(vertex)
    doSomethingFunction(vertex)
//  println("Visit complete: $vertex") // ์ฝ˜์†” ์ฐฝ์ด ๋”๋Ÿฌ์›Œ์ง€๋ฏ€๋กœ, ์ƒ๋žต

    if (vertex == goal) { // ๊ฒฝ๋กœ ํƒ์ƒ‰ ๋ฌธ์ œ๋ผ๋Š” ๊ฐ€์ • ํ•˜์˜ ์ฝ”๋“œ์ด๋ฏ€๋กœ ์„ ์–ธ๋œ if๋ฌธ.
        println(path)
    } else {
        // (4) ์ •์ ์˜ ์ด์›ƒ ์ •์ ๋งˆ๋‹ค (5)์„ ์ˆ˜ํ–‰
        for (neighborVertex in mapOfAdjacencyArray[vertex]!!) {
            // (5) visited ๋ชฉ๋ก์— ์—†๋‹ค๋ฉด, ์ด์›ƒ ์ •์ ์„ ์žฌ๊ท€ ํ˜ธ์ถœํ•œ๋‹ค
            if (neighborVertex !in visited) {
                dfs(mapOfAdjacencyArray, neighborVertex, visited)
            }
        }
    }

    visited.remove(vertex) // ๋ฐฑํŠธ๋ž˜ํ‚น
    doSomethingFunction2() // ๋ฐฑํŠธ๋ž˜ํ‚น ํ›„ ํ•  ์ผ. ์—ฌ๊ธฐ์„  doSomethingFunction2()๋กœ ํ‘œํ˜„ํ•จ.
}

fun <T> doSomethingFunction(vertex: T) {
    path.add(vertex.toString())
}

fun doSomethingFunction2() {
    path.removeAt(path.size - 1)
}

/* ์ถœ๋ ฅ ๊ฒฐ๊ณผ

๋ชจ๋“  ๊ฒฝ๋กœ:
[๊ฐ•์•„์ง€, ๊ณ ์–‘์ด, ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด]
[๊ฐ•์•„์ง€, ์‚ฌ์Šด, ํฐ๋จธ๋ฆฌ์˜ค๋ชฉ๋ˆˆ์ด]

*/

์œ„์—์„œ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ ค๊ณ  ๋ฐฑํŠธ๋ž˜ํ‚น์„ 'ํฌ๊ธฐ', '๊ฐ€์ง€์น˜๊ธฐ'๋ผ๋Š” ๋‹จ์–ด๋ฅผ ํ†ตํ•ด ์„ค๋ช…ํ–ˆ์ง€๋งŒ, ์‚ฌ์‹ค ํฌ๊ธฐ๋ผ๊ธฐ๋ณด๋‹จ '๋˜๋Œ์•„๊ฐ', '์ดˆ๊ธฐํ™”'์— ๊ฐ€๊น๋‹ค. '๊ฐ€์ง€์น˜๊ธฐ'์˜ ๋Šฌ์•™์Šค์ฒ˜๋Ÿผ ์™„์ „ํ•˜๊ฒŒ ๋ฒ„๋ ค ๋ฐฐ์ œํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ข€ ๋” ์™€๋‹ฟ๋„๋ก ๋น„์œ ๋ฅผ ํ•˜์ž๋ฉด, Ctrl +  Z๋ฅผ ํ†ตํ•œ ๋˜๋Œ๋ฆฌ๊ธฐ(Undo)๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์œ„ ์ฝ”๋“œ๋ฅผ ๋ด๋„, ๋ฐฑํŠธ๋ž˜ํ‚น์˜ ์–ด๋–ค ๋™์ž‘์ธ์ง€์— ๋Œ€ํ•œ ๋А๋‚Œ์€ ์•Œ๊ฒ ์ง€๋งŒ ๊ทธ ๋™์ž‘์„ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ–ˆ๋‹ค๊ณ ๊นŒ์ง€ ํ•˜๊ธด ํž˜๋“ค ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์•„๋ž˜๋ฅผ ์ฐธ์กฐํ•˜์ž.
 
๋ฐฑํŠธ๋ž˜ํ‚น์ด ํ•„์š”ํ•œ๋ฐ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒ๊ธฐ๋Š” ์ผ

[๋ฐฑ์ค€] 26169 (์„ธ ๋ฒˆ ์ด๋‚ด์— ์‚ฌ๊ณผ๋ฅผ ๋จน์ž)

#1 ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ทธ๋ž˜ํ”„ - ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ (DFS, Depth-First Search)#1 ๊ทธ๋ž˜ํ”„์˜ ํƒ์ƒ‰ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ - ์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „์œ„ํ‚ค๋ฐฑ๊ณผ, ์šฐ๋ฆฌ ๋ชจ๋‘์˜ ๋ฐฑ๊ณผ์‚ฌ์ „. ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์˜ ์• 

kenel.tistory.com

์œ„๋Š” ๋ฐฑํŠธ๋ž˜ํ‚น์ด ๊ฐ€๋ฏธ๋œ DFS ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋‹ค๋ฃฌ ๊ฒŒ์‹œ๊ธ€์ด๋‹ค. ๋˜, ์ด ๊ฒŒ์‹œ๊ธ€์˜ '์‹คํŒจํ•œ ์ฝ”๋“œ' ๋ถ€๋ถ„์— ๋ฐฑํŠธ๋ž˜ํ‚น์ด ํ•„์š”ํ•œ ์ด์œ ๊ฐ€ ๋„์‹๋„๋ฅผ ํ†ตํ•ด ์ง๊ด€์ ์œผ๋กœ ์„ค๋ช…๋˜์–ด์žˆ๋‹ค.
 

#4 ์š”์•ฝ

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์€ ์ธ์ ‘ ๋ฐฐ์—ด์˜ ์›์†Œ๋“ค์„ (์žฌ๊ท€ ํ˜ธ์ถœ ๊ตฌ์กฐ๋ผ๋Š”) Stack์— ๋„ฃ๋Š”๋‹ค.