์•Œ๊ณ ๋ฆฌ์ฆ˜/๊ฐœ๋…

[Swift] DFS(Depth-First Search, ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰)์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž

๊ฒฝํ‘ธ 2023. 2. 5. 18:00
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”~

 

์˜ค๋Š˜์€ ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

 

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰( DFS, Depth-First Search )์ด๋ž€?

 

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์€ ํƒ์ƒ‰ํ•˜๊ณ ์ž ํ•˜๋Š” ๋…ธ๋“œ๋“ค์˜ ์ž์‹ ๋…ธ๋“œ๋ถ€ํ„ฐ ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹์„ ๋งํ•ฉ๋‹ˆ๋‹ค. 

 

์•„๋ž˜์˜ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ๊ทธ๋ž˜ํ”„์—์„œ BFS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

 

 

์•ž์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ž์‹ ๋…ธ๋“œ๋ถ€ํ„ฐ ํ™•์ธํ•˜๋Š”๋ฐ 

์˜ˆ๋ฅผ ๋“ค์–ด์„œ 1์„ ๊ฐ€์žฅ ๋จผ์ € ํƒ์ƒ‰ํ•˜๊ณ  ๋‚˜๋ฉด 8, 6, 10, 7, 4 ... ์„ ์ˆœ์„œ๋Œ€๋กœ ํƒ์ƒ‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์ฆ‰, ํƒ์ƒ‰ํ•˜๊ณ ์žํ•˜๋Š” ๋…ธ๋“œ์˜ ์ž์‹ ๋…ธ๋“œ๋“ค์„ ๋ชจ๋‘ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

 

BFS์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ๊ธฐ์„œ 8๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋“  2๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋“  ์ˆœ์„œ๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 

์ค‘์š”ํ•œ ์ ์€ ์ž์‹ ๋…ธ๋“œ๋“ค์„ ์šฐ์„  ํƒ์ƒ‰ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

โœ”๏ธŽ Swift๋กœ ๊ตฌํ˜„ํ•ด ๋ณด๊ธฐ

์œ„์˜ ์ด๋ฏธ์ง€์— ์žˆ๋Š” ๊ทธ๋ž˜ํ”„๋ฅผ ํ†ตํ•ด DFS๋ฅผ ๊ตฌํ˜„ํ•ด ๋ณด์ž.

 

1. ํ( Queue )

 

DSF๋Š” ๋ณดํ†ต ํ•œ ๊ฐœ์˜ ํ์™€ ํ•œ ๊ฐœ์˜ ์Šคํƒ์œผ๋กœ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

(1) ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ

(2) ๋ฐฉ๋ฌธํ•ด์•ผ ํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ์Šคํƒ

 

BFS์—์„œ๋Š” ๋‘๊ฐœ์˜ ํ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ

DFS์—์„œ ์Šคํƒ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

 

BFS์—์„œ๋Š”  Queue์˜ FIFO ์„ฑ์งˆ์„ ์ด์šฉํ•ด ์ธ์ ‘๋ฆฌ์ŠคํŠธ์—์„œ depth๊ฐ€ ๊ฐ€์žฅ ๋‚ฎ์€ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๊ณ 

DFS์—์„œ๋Š” Stack์˜ LIFO ์„ฑ์งˆ์„ ์ด์šฉํ•ด ์ธ์ ‘๋ฆฌ์ŠคํŠธ์—์„œ depth๊ฐ€ ๊ฐ€์žฅ ๊นŠ์€ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์œ„์˜ ์ด๋ฏธ์ง€๋ฅผ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

"1"์„ ๊ฐ€์žฅ ๋จผ์ € ์„ ํƒํ•ด ํƒ์ƒ‰ํ•˜๋ฉด

 

1. BFS

 

  visitQueue needVisitQueue
๋ฃจํ”„ 1 ["1"] ["8", "5", "2"]
๋ฃจํ”„ 2 ["1", "8"] ["2", "5", "6", "4", "3"]
๋ฃจํ”„ 3 ["1", "8", "5"] ["2", "6", "4", "3"]

 

์œ„์™€ ๊ฐ™์ด ํ๋ฅผ ์ด์šฉํ•˜๊ฒŒ๋˜๋ฉด ๊ฐ™์€ depth๋ถ€ํ„ฐ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

 

2. DFS

 

  visitQueue needVisitStack
๋ฃจํ”„ 1 ["1"] ["2", "5", "8"]
๋ฃจํ”„ 2 ["1", "8"] ["2", "5", "3", "4", "6"]
๋ฃจํ”„ 3 ["1", "8", "6"] ["2", "5", "3", "4", "7", "10"]

 

์œ„์™€ ๊ฐ™์ด ์Šคํƒ์„ ์‚ฌ์šฉํ•˜๋ฉด depth๊ฐ€ ๋” ๊นŠ์€ ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

 

ํ์™€ ์Šคํƒ์€ ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ ๋‹ค๋ค˜์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

[ ํ(Queue) ]

 

 

[Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ํ(Queue)

์•ˆ๋…•ํ•˜์„ธ์š”~ ์˜ค๋Š˜์€ ์Šคํƒ์— ์ด์–ด์„œ ํ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. [ ์Šคํƒ ํฌ์ŠคํŒ… ] [Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ์Šคํƒ(Stack) ์•ˆ๋…•ํ•˜์„ธ์œ ~ ์˜ค๋Š˜์€ ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘์—์„œ ์Šคํƒ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค! ์‚ฌ์‹ค ์ด

pooh-footprints.tistory.com

[ ์Šคํƒ(Stack) ]

 

 

[Swift] ์ž๋ฃŒ๊ตฌ์กฐ - ์Šคํƒ(Stack)

์•ˆ๋…•ํ•˜์„ธ์š”~ ์˜ค๋Š˜์€ ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘์—์„œ ์Šคํƒ์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค! ์‚ฌ์‹ค ์ด์ „์— ํ•™์Šต์„ ํ–ˆ์ง€๋งŒ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ ์  ๊ฐ€๋ฌผ๊ฐ€๋ฌผํ•ด์ง€๋”๋ผ๊ตฌ์š” ๊ทธ๋ž˜์„œ Swift๋กœ ๋‹ค์‹œ๊ธˆ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณผ๊นŒ ํ•ฉ

pooh-footprints.tistory.com

 

2. ์ธ์ ‘๋ฆฌ์ŠคํŠธ( Adjacency List )

 

๊ทธ๋ž˜ํ”„๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š”

์ธ์ ‘ ํ–‰๋ ฌ ๊ทธ๋ž˜ํ”„์™€ ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹ ๋‘ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ๋Š” ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ธ์ ‘๋ฆฌ์ŠคํŠธ๋ž€ ๋ง ๊ทธ๋Œ€๋กœ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ๋ฆฌ์ŠคํŠธ๋กœ ๋‚˜์—ดํ•œ ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

 

1 8 5 2  
8 1 6 4 3
5 1      
2 1 9    
6 8 10 7  
4 8      
3 8      
9 2      
10 6      
7 6      

 

์œ„์˜ ๊ฐ’๋“ค์„ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

let graph: [String: [Int]] = [
    "1" : [8, 5, 2],
    "8" : [1, 6, 4, 3],
    "5" : [1],
    "2" : [1, 9],
    "6" : [8, 10, 7],
    "4" : [8],
    "3" : [8],
    "9" : [2],
    "10" : [6],
    "7" : [6]
]

 

3. DFS

์„ค๋ช…์€ ์ฃผ์„์œผ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

func depthFirstSearch(graph: [String: [Int]], start: String) -> [String] {

    // ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ํ
    var visitedQueue: [String] = []
    // ๋ฐฉ๋ฌธํ•ด์•ผํ•˜๋Š” ๋…ธ๋“œ๋ฅผ ์ €์žฅํ•˜๋Š” ์Šคํƒ
    var needVisitStack: [String] = [start]
    
    while !needVisitStack.isEmpty {
        
        let node: String = String(needVisitStack.removeLast())
        
        // ์ด๋ฏธ ๋ฐฉ๋ฌธํ–ˆ๋˜ ๋…ธ๋“œ๋ผ๋ฉด continue ์ฒ˜๋ฆฌ
        if visitedQueue.contains(node) {
            continue
        }
        
        visitedQueue.append(node)
        // ์ธ์ ‘ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •
        // ๋งŒ์•ฝ ๊ฐ€์žฅ ์ฒ˜์Œ์— "1"์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด 1๊ณผ ์ธ์ ‘ํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ needVisitStack์— ์ถ”๊ฐ€ํ•˜๋Š” ๊ณผ์ •
        needVisitStack += graph[node].map{ $0.map { String($0) } }?.reversed() ?? []
    }
    
    return visitedQueue
}

print(depthFirstSearch(graph: graph, start: "1"))
// ["1", "8", "6", "10", "7", "4", "3", "5", "2", "9"]

 

์—ฌ๊ธฐ๊นŒ์ง€ ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์ด๋งŒ ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป ๐Ÿ‘‹๐Ÿป

๋ฐ˜์‘ํ˜•