A
, B
등 꼭지점을 말한다.N = 7
edge_data = [1, 2, 1, 5, 1, 3, 2, 6, 3, 4, 4, 5, 5, 7, 6, 7]
adjacency_list = [[] for _ in range(N+1)]
for i in range(0, len(edge_data), 2):
# 두 개의 노드 정보를 담는다.
node_num_1 = edge_data[i]
node_num_2 = edge_data[i+1]
# 무방향 그래프이므로 두 개의 정보를 저장한다.
adjacency_list[node_num_1].append(node_num_2)
adjacency_list[node_num_2].append(node_num_1)
edge_data
에는 간선의 정보가 담겨 있다. 맨 처음 두 개는 1번 노드에서 2번 노드로 이어진다는 의미이다. 무방향 그래프를 구현하고 있으므로 반대 방향으로도 이어진다는 정보를 추가해야 한다.
[[],
[2, 5, 3],
[1, 6],
[1, 4],
[3, 5],
[1, 4, 7],
[2, 7],
[5, 6]]
0번 노드는 존재하지 않지만 인덱스가 zero-based이기 때문에 편의상 위와 같이 구성했다.
N = 7
edge_data = [1, 2, 1, 5, 1, 3, 2, 6, 3, 4, 4, 5, 5, 7, 6, 7]
adjacency_matrix = [[0] * (N + 1) for _ in range(N + 1)]
for i in range(0, len(edge_data), 2):
node_num_1 = edge_data[i]
node_num_2 = edge_data[i+1]
adjacency_matrix[node_num_1][node_num_2] = 1
adjacency_matrix[node_num_2][node_num_1] = 1
이차원 배열을 사용한 것을 제외하곤, 인접리스트와 로직은 비슷하다.
[
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 1, 0]
]
이번에도 마찬가지로 편의상 (N+1)행, (N+1)열을 이용했다. 무방향 그래프이므로 대칭행렬을 이룬다.
그래프는 보편적으로 깊이우선탐색과 너비우선탐색을 이용한다.
스택 자료구조를 이용하면 깊이우선 탐색을 구현할 수 있다.
visited = [0] * (N + 1)
stack = []
def DFS(n):
stack.append(1)
while stack:
tmp = stack.pop()
if visited[tmp] == 0:
visited[tmp] = 1
print(tmp, end=" ")
for node in adjacency_list[tmp]:
stack.append(node)
return
- 1번부터 순회를 시작했으므로 stack에 1을 저장한다.
- stack에서 맨 뒤에 요소를 pop한 뒤 방문 여부를 확인한다.
- 방문하지 않았을 경우 방문 체크를 하고 해당 노드에서 접근 가능한 모든 노드를 stack에 저장한다.
- stack이 빌 때까지 반복하며 모든 노드를 방문했을 경우 종료된다.
인접리스트 방식을 사용해서 그래프 정보를 저장했다. visited
리스트의 역할은 방문했던 노드를 체크해서 다시 방문하는 것을 방지하는 것이다.
n
은 순회를 시작할 노드의 번호이며, 필자는 1번에서 시작했다.
결과 : 1 3 4 5 7 6 2
큐 자료구조를 이용하면 깊이우선 탐색을 구현할 수 있다.
visited = [0] * (N + 1)
queue = []
def BFS(n):
queue.append(1)
while queue:
tmp = queue.pop(0)
if visited[tmp] == 0:
visited[tmp] = 1
print(tmp, end=" ")
for node in adjacency_list[tmp]:
queue.append(node)
return
탐색할 노드를 저장할 자료구조가 스택이 아닌 큐를 사용하는 것을 제외하면 깊이우선탐색과 동일한 로직으로 작동한다.
결과 : 1 2 5 3 6 4 7