Data Structure & Algorithm

[์ž๋ฃŒ๊ตฌ์กฐ] DFS(๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰) & BFS(๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰) (in python)

์—ฌ๋‰ด๋ˆ„ 2024. 1. 21. 22:08
728x90

๐Ÿ’ก ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰

  • ํ•˜๋‚˜์˜ ๋…ธ๋“œ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ์ •์ ๋“ค์„ ํ•œ ๋ฒˆ์”ฉ ๋ฐฉ๋ฌธํ•˜๋Š” ๊ฒƒ

๐Ÿ’ก DFS (๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰)

DFS๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๊นŠ์ด๋ฅผ ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์ „ํšŒ ์ˆœํšŒ๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ, "๋ฃจํŠธ ๋…ธ๋“œ -> ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ -> ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ" ์ˆœ์œผ๋กœ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด ๊ณผ์ •์ด ์žฌ๊ท€์ ์œผ๋กœ ๋ฐ˜๋ณต๋œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ๋œ๋‹ค. ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์— ๋ฐฉ๋ฌธํ•˜๋ฉด ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์—์„œ๋Š” ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธํ•˜๊ณ  ๊ทธ ๋ฃจํŠธ ๋…ธ๋“œ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ -> ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ถœ์ฒ˜ : https://velog.io/@tomist0930/dfs

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ๋”์šฑ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ๋งŒ์•ฝ ๊ทธ๋ž˜ํ”„๊ฐ€ ์œ„์™€ ๊ฐ™๋‹ค๊ณ  ํ•˜๋ฉด DFS์˜ ์ˆœํšŒ ์ˆœ์„œ๋Š” 0 - 1 - 2 - 3 - 4 - 5๊ฐ€ ๋œ๋‹ค.

  • ๋ฃจํŠธ ๋…ธ๋“œ์˜ 0 ๋ฐฉ๋ฌธ
  • 0์ด ๋ฃจํŠธ ๋…ธ๋“œ์ธ ํŠธ๋ฆฌ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์ธ 1์„ ๋ฐฉ๋ฌธ -> 1์€ ์ž์‹๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ 1์ด ๋ฃจํŠธ ๋…ธ๋“œ์ธ ์„œ๋ธŒํŠธ๋ฆฌ ํƒ์ƒ‰
  • 1์ด ๋ฃจํŠธ ๋…ธ๋“œ์ธ ํŠธ๋ฆฌ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์ธ 2๋ฅผ ๋ฐฉ๋ฌธ -> 2๋Š” ๋ฆฌํ”„๋…ธ๋“œ์ด๋ฏ€๋กœ ๋”์ด์ƒ ํƒ์ƒ‰ X
  • 1์ด ๋ฃจํŠธ ๋…ธ๋“œ์ธ ํŠธ๋ฆฌ์˜ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์ธ 3์„ ๋ฐฉ๋ฌธ -> 3์€ ๋ฆฌํ”„๋…ธ๋“œ์ด๋ฏ€๋กœ ๋”์ด์ƒ ํƒ์ƒ‰ X
  • 0์ด ๋ฃจํŠธ ๋…ธ๋“œ์ธ ํŠธ๋ฆฌ์˜ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์ธ 4๋ฅผ ๋ฐฉ๋ฌธ  -> 4๋Š” ์ž์‹๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ 4๊ฐ€ ๋ฃจํŠธ ๋…ธ๋“œ์ธ ์„œ๋ธŒํŠธ๋ฆฌ ํƒ์ƒ‰
  • 4๊ฐ€ ๋ฃจํŠธ ๋…ธ๋“œ์ธ ํŠธ๋ฆฌ์˜ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์ธ 5๋ฅผ ๋ฐฉ๋ฌธ -> 5๋Š” ๋ฆฌํ”„๋…ธ๋“œ์ด๋ฏ€๋กœ ๋”์ด์ƒ ํƒ์ƒ‰ X
  • ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜์˜€์œผ๋ฏ€๋กœ, ํƒ์ƒ‰ ์ข…๋ฃŒ

๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

visit = [False] * (n + 1) # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ํ‘œ์‹œํ•  ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ

# dfs ํ•จ์ˆ˜
def dfs(node):
  visit[node] = True # ๋ฐฉ๋ฌธ ๋…ธ๋“œ True๋กœ ํ‘œ์‹œ
  for i in graph[node]: # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ž์‹๋…ธ๋“œ์— ๋Œ€ํ•ด
    if not visit[i]: # ๋งŒ์•ฝ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ผ๋ฉด
      dfs(i) # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ž์‹๋…ธ๋“œ์— ๋Œ€ํ•ด dfs ์‹ค์‹œ

 

๊ทธ๋ฆฌ๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํฌ๊ฒŒ ๋‘๊ฐ€์ง€ ๊ฒฝ์šฐ๋กœ ๋‚˜๋ˆ„์–ด ํ™œ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

(1) ํŠธ๋ฆฌ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ >> ์•„๋งˆ ์ด๊ฒŒ ๋Œ€๋ถ€๋ถ„

ํŠธ๋ฆฌ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋Š” ์˜๋ฏธ๋Š” ์ด์ฐจ์› ๋ฐฐ์—ด ์•ˆ์—์„œ ๋Œ€๊ฐ์„ , ์–‘์˜†์œผ๋กœ ์›€์ง์ผ ์ˆ˜ ์žˆ์„ ๋•Œ, ์›€์ง์ผ ์ˆ˜ ์žˆ๋Š” ์˜์—ญ์˜ ๊ฐœ์ˆ˜ ์ •๋„๋กœ ํ‘œํ˜„๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์‹ค์ œ๋กœ ํ’€์—ˆ๋˜ ๋ฌธ์ œ๋ฅผ ์˜ˆ์‹œ๋กœ ๋“ค์–ด๋ณด์ž๋ฉด, ๋ฐฐ์ถ”๊ฐ€ ์ด์ฐจ์› ๋ฐฐ์—ด ์•ˆ์— ๋“ฌ์„ฑ๋“ฌ์„ฑ ์‹ฌ์–ด์ ธ์žˆ๋Š”๋ฐ & ์‚ด์ถฉ์ œ์˜ ํšจ๊ณผ๊ฐ€ ๋Œ€๊ฐ์„ , ์–‘์˜†๊นŒ์ง€๋งŒ ์žˆ์„ ๋•Œ, ๋ชจ๋“  ๋ฐฐ์ถ”์— ์‚ด์ถฉ์ œ์˜ ํšจ๊ณผ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์‚ด์ถฉ์ œ์˜ ์ด ๊ฐœ์ˆ˜๋Š” ๋ช‡ ๊ฐœ์ธ๊ฐ€์˜ ๋А๋‚Œ !

์ด๋Ÿด๋•Œ๋Š” "์—ฐ๊ฒฐ๋œ ๊ทธ๋ž˜ํ”„๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  >> ํƒ์ƒ‰์ด ๋๋‚˜๋ฉด count + 1 >> ๋‹ค์Œ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ์— ๋Œ€ํ•ด dfs๋ฅผ ์ ์šฉํ•˜์—ฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๊ทธ๋ž˜ํ”„๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  >> ํƒ์ƒ‰์ด ๋๋‚˜๋ฉด count + 1"์˜ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

cnt = 0
for i in range(1, n + 1): # ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต๋ฌธ ์‹คํ–‰
    if not visited[i]: # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ์ด๋ฉด
        if not graph[i]: # ์ •์ ์€ ์กด์žฌํ•˜์ง€๋งŒ & ์—ฐ๊ฒฐ๋œ ์ •์ ์ด ์—†์„ ๋•Œ = ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ ๊ทธ๋ž˜ํ”„์ผ ๋•Œ
            cnt += 1 # count + 1
            visited[i] = True # ๋ฐฉ๋ฌธํ–ˆ๋‹ค๊ณ  ํ‘œ์‹œ
        else: # ์—ฐ๊ฒฐ๋œ ์ •์ ์ด ์žˆ์œผ๋ฉด
            dfs(i) # ๋…ธ๋“œ์— ๋Œ€ํ•ด dfs ์‹คํ–‰
            cnt += 1 # count + 1

print(cnt)

 

์‚ฌ์‹ค ์•„๋ž˜์ฒ˜๋Ÿผ๋„ ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ๋Š”๋ฐ, ์—ฐ๊ฒฐ๋œ ๊ฐ„์„ ์ด ์—†๋Š” ์ •์ ์— ๋Œ€ํ•ด ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ๊ตณ์ด ํ˜ธ์ถœํ•  ํ•„์š”๋Š” ์—†์œผ๋‹ˆ ์œ„์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์งœ๋Š”๊ฒŒ ๋” ํšจ์œจ์ ์ผ ๊ฒƒ ๊ฐ™๋‹ค.

cnt = 0
for i in range(1, n + 1): # ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต๋ฌธ ์‹คํ–‰
    if not visited[i]: # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ์ด๋ฉด
    	dfs(i) # ๋…ธ๋“œ์— ๋Œ€ํ•ด dfs ์‹คํ–‰
        cnt += 1 # count + 1

print(cnt)

 

(2) ํŠธ๋ฆฌ์˜ ๊ฐœ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ผ ๋•Œ

๊ทธ๋ƒฅ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์œผ๋กœ ํŠธ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ์‹œ์ž‘๋…ธ๋“œ๋งŒ ์•„๋ž˜์ฒ˜๋Ÿผ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

dfs(1)

 

๐Ÿ’ก BFS (๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰)

BFS๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋„ˆ๋น„๋ฅผ ์šฐ์„ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋ ˆ๋ฒจ ์ˆœ ์ˆœํšŒ๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋‚ฎ์€ ๋ ˆ๋ฒจ๋ถ€ํ„ฐ ์ฐจ๋ก€๋Œ€๋กœ ์ˆœํšŒํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. 0๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ -> 1๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ -> 2๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์‹์œผ๋กœ !

์ถœ์ฒ˜ : https://velog.io/@tomist0930/dfs

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•ด๋ณด๋ฉด, BFS์˜ ์ˆœํšŒ ์ˆœ์„œ๋Š” 0 - 1 - 4 - 2 - 3 - 5 ๊ฐ€ ๋˜๊ณ , DFS๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๋‹ค.

  • ๋ ˆ๋ฒจ 0์˜ 0 ํƒ์ƒ‰
  • ๋ ˆ๋ฒจ 1์˜ 1 -> 4 ํƒ์ƒ‰
  • ๋ ˆ๋ฒจ 2์˜ 2 -> 3 -> 5 ํƒ์ƒ‰
  • ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ–ˆ์œผ๋ฏ€๋กœ ํƒ์ƒ‰ ์ค‘์ง€

๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

from collections import deque

# ๋ฐฉ๋ฌธ ๋…ธ๋“œ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
visit = [False] * (n + 1)

# bfs ํ•จ์ˆ˜
def bfs(node):
  visit[node] = True # ์‹œ์ž‘ ๋…ธ๋“œ ๋ฐฉ๋ฌธ
  queue = deque([node]) # queue ์ƒ์„ฑ
  while queue: # queue์— ์›์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๋™์•ˆ
    v = queue.popleft() # queue์˜ ๊ฐ€์žฅ ์™ผ์ชฝ์˜ ๊ฐ’์„ ์ถ”์ถœ (๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ๊ฐ’)
    for i in graph[v]: # v์˜ ๋ชจ๋“  ์ž์‹๋…ธ๋“œ์— ๋Œ€ํ•ด
      if not visit[i]: # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋Š”
        queue.append(i) # queue์— ์ถ”๊ฐ€ํ•˜๊ณ 
        visit[i] = True # ๋ฐฉ๋ฌธํ–ˆ์Œ์„ ํ‘œ์‹œํ•ด์คŒ

 

์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉฐ ์‹คํ–‰๋˜๋Š” DFS์™€ ๋‹ฌ๋ฆฌ while๋ฌธ์„ ํ†ตํ•ด ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. ๊ทธ๋ž˜์„œ์ธ์ง€, BFS์™€ DFS๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ์„ ๋•Œ BFS๊ฐ€ ์„ฑ๋Šฅ์ด ๋” ์ข‹์•˜๋˜ ์ ์ด ๋งŽ์•˜๋‹ค. ํ’€์ด์˜ ๋ฐฉ์‹์€ ์œ„์˜ DFS์ฒ˜๋Ÿผ ๋™์ผํ•˜๊ฒŒ ํŠธ๋ฆฌ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ผ ๋•Œ & ํ•œ ๊ฐœ์ผ ๋•Œ๋กœ ๋‚˜๋ˆ„์–ด ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์„ค๋ช…์€ ์œ„์— ์ฐธ๊ณ  !

 

(1) ํŠธ๋ฆฌ์˜ ๊ฐœ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ ๋•Œ >> ์•„๋งˆ ์ด๊ฒŒ ๋Œ€๋ถ€๋ถ„

cnt = 0
for i in range(1, n + 1): # ๋ชจ๋“  ๋…ธ๋“œ์— ๋Œ€ํ•ด ๋ฐ˜๋ณต๋ฌธ ์‹คํ–‰
    if not visited[i]: # ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ์ด๋ฉด
        if not graph[i]: # ์ •์ ์€ ์กด์žฌํ•˜์ง€๋งŒ & ์—ฐ๊ฒฐ๋œ ์ •์ ์ด ์—†์„ ๋•Œ = ํ•˜๋‚˜์˜ ๋…ธ๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ ๊ทธ๋ž˜ํ”„์ผ ๋•Œ
            cnt += 1 # count + 1
            visited[i] = True # ๋ฐฉ๋ฌธํ–ˆ๋‹ค๊ณ  ํ‘œ์‹œ
        else: # ์—ฐ๊ฒฐ๋œ ์ •์ ์ด ์žˆ์œผ๋ฉด
            bfs(i) # ๋…ธ๋“œ์— ๋Œ€ํ•ด bfs ์‹คํ–‰
            cnt += 1 # count + 1

print(cnt)

 

 

(2) ํŠธ๋ฆฌ์˜ ๊ฐœ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ผ ๋•Œ

bfs(1)

๐Ÿ’ก ํƒ์ƒ‰์ˆœ์„œ : DFS & BFS ๋น„๊ต

  • DFS : F - B - A - D - C - E - G - I - H
  • BFS : F - B - G - A - D - I - C - E - H
728x90