선수지식으로 트리, 그래프를 배웠다.
: 노드로 이루어진 자료 구조
: 단순히 노드(N, node)와 그 노드를 연결하는 간선(E, edge)을 하나로 모아 놓은 자료 구조
참고.. 이진트리, 트리순회는 또 다른 chapter가 있으니 거기서 깊게 다루자!
루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법.
즉, 넓게(wide) 탐색하기 전에 깊게(deep) 탐색하는 것이다.
Stack에 시작할 노드를 하나 넣고, 해당 노드의 Child 노드를 다 넣은 후 자식이 없다면, stack에서 꺼낸다 이때 자식 노드가 있다면 Stack에 추가하고, 없다면 출력(Print)한다.
한번 넣었던 노드는 다시 넣지 않는다.
스택이 다 비었다면 순회가 완료된 것이다.
20초 ~ 3:10초
https://www.youtube.com/watch?v=_hxFgg7TLZQ
const graph = {
A: ["B", "C"],
B: ["A", "D"],
C: ["A", "G", "H", "I"],
D: ["B", "E", "F"],
E: ["D"],
F: ["D"],
G: ["C"],
H: ["C"],
I: ["C", "J"],
J: ["I"]
};
const DFS = (graph, startNode) => {
const visited = []; // 탐색을 마친 노드들
let needVisit = []; // 탐색해야할 노드들
needVisit.push(startNode); // 노드 탐색 시작
while (needVisit.length !== 0) { // 탐색해야할 노드가 남아있다면
const node = needVisit.shift(); // queue이기 때문에 선입선출, shift()를 사용한다.
if (!visited.includes(node)) { // 해당 노드가 탐색된 적 없다면
visited.push(node);
needVisit = [...graph[node], ...needVisit];
}
}
return visited;
};
console.log(DFS(graph, "A"));
// ["A", "B", "D", "E", "F", "C", "G", "H", "I", "J"]
def dfs(v, graph):
stack = [v]
visited = set()
while stack:
a = stack.pop()
if a in visited: continue
print(a, end = " ")
visited.add(a)
if graph.get(a):
stack.extend(sorted(graph[a], reverse=True))
재귀를 이용하면 코드가 더욱 간결하고 깔끔해진다.
5:25 ~ 7:53
https://www.youtube.com/watch?v=_hxFgg7TLZQ
+) 이진트리 순회, 조합 참고 - DFS 총정리
https://velog.io/@padd60/JS-%EC%BD%94%ED%85%8C-%EC%9E%AC%EA%B7%80%ED%95%A8%EC%88%98-%EB%B0%8F-DFS-%EC%A0%95%EB%A6%AC-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%9D%91%EC%9A%A9
function DFS(x){
if(x===1) return;
else{
console.log(x);
DFS(x-1);
console.log(x+1);
}
}
DFS(4);
스택에 담는다고 생각하면 편하다.
함수를 선언할 때 스택이 만들어 지는데, 스택 안에는 지역변수, 매개변수, 복귀 주소가 들어있다.
# 재귀함수 사용 1
def dfs(v, graph, visited):
if v in visited: return
print(v, end = " ")
visited.add(v)
# 자식 노드가 있을 때
if graph.get(v):
for c in graph[v]:
dfs(c, graph, visited)
DFS는 그래프(정점의 수: N, 간선의 수: E)의 모든 간선을 조회한다.
인접 리스트로 표현된 그래프: O(N+E)
인접 행렬로 표현된 그래프: O(N^2)
문제
https://school.programmers.co.kr/learn/courses/30/lessons/43162
풀이
https://velog.io/@timointhebush/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-DFS-BFS-Python
코드
def solution(n, computers):
answer = 0
visited = [False for i in range(n)]
for com in range(n):
if visited[com] == False:
DFS(n, computers, com, visited)
answer += 1 #DFS로 최대한 컴퓨터들을 방문하고 빠져나오게 되면 그것이 하나의 네트워크.
return answer
def DFS(n, computers, com, visited):
visited[com] = True
for connect in range(n):
if connect != com and computers[com][connect] == 1: #연결된 컴퓨터
if visited[connect] == False: