깊이 우선 탐색 (Depth First Search)
깊이(자식 노드)를 우선적으로 탐색하는 방법
위와 같은 그래프일 때,
let graph = [[1, 2],
[0, 3, 4],
[0],
[1, 5, 6],
[1],
[3],
[3]
]
var isVisited = Array(repeating: false, count: graph.count) // 방문한 노드인지 확인하는 배열
func depthFirstSearch(start: Int) -> [Int] {
var searchList: [Int] = []
var needVisitStack = [start] // 전달받은 start 노드부터 시작
while !needVisitStack.isEmpty {
let node = needVisitStack.removeLast() // 방문할 노드에서 하나 꺼내기
if isVisited[node] { continue } // 이미 방문한 노드이면 지나가기
isVisited[node] = true // 방문함으로 표시
searchList.append(node)
graph[node].forEach {
needVisitStack.append($0) // 인접한 노드를 방문할 노드 리스트에 넣기
}
}
return searchList
}
func depthFirstSearch(start: Int) {
isVisited[start] = true
graph[start].forEach {
if isVisited[$0] != true {
isVisited[$0] = true
print($0)
depthFirstSearch(start: $0)
}
}
}
너비 우선 탐색 (Breadth First Search)
인접한 노드(형제 노드)를 우선적으로 탐색하는 방법
func breadthFirstSearch(start: Int) -> [Int] {
var serchList: [Int] = [start] // 방문한 노드를 담는 배열
let queue = Queue<Int>() // 방문할 노드를 담는 큐
queue.enqueue(start)
while !queue.isEmpty { // 방문할 노드가 없을 때까지 반복
guard let node = queue.dequeue() else { return [] }
isVisited[node] = true // 방문 표시로 변경
graph[node].forEach {
if isVisited[$0] != true {
queue.enqueue($0) // 인접한 노드를 방문할 큐에 넣고
serchList.append($0)
isVisited[$0] = true // 바로 방문
}
}
}
return serchList
}
참고로 Queue
는 구현한 타입으로 그냥 [Int]
을 사용해도 무방하다!
참고