728x90
- 인접 행렬 : 2차원 배열로 그래프의 연결 관계를 표현하는 방식
- 간선 정보를 저장하기 위해 O(V^2)만큼의 메모리 공간 필요
- 특정한 노드 A에서 다른 특정한 노드 B로 이어진 간선의 비용 : O(1)
- V : 노드
0 1 2 #노드 번호
0 0 7 5 #거리
1 7 0 ~
2 5 ~ 0
- 인접 리스트 : 리스트로 그래프의 연결 관계를 표현하는 방식
- 간선 정보를 저장하기 위해 O(E)만큼의 메모리 공간 필요
- 특정한 노드 A에서 다른 특정한 노드 B로 이어진 간선의 비용 : O(V)
- E : 간선
graph = [[] for _ in range(노드개수)]
graph[0].append((노드번호, 노드거리))
graph[0].append((노드번호, 노드거리))
graph[1].append((노드번호, 노드거리))
...
BFS(넓이 우선 탐색)
- 시간 복잡도 : O(V+E)
- 하나의 경우의 수에 대한 다음 단계의 모든 경우의 수를 조사하면서 해를 찾는 과정
- 정점들과 같은 레벨에 있는 노드들 (형제 노드들)을 먼저 탐색하는 방식
- 동작 방식
- 탐색 시작 노드를 큐에 삽입하고 방문 처리를 함
- 큐에서 노드를 꺼내 해당 노드의 인접 노드 중에서 방문하지 않은 노드를 모두 큐에 삽입하고 방문 처리를 함
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복함
from collections import deque
def bfs(graph, start, visited):
queue = deque([start])
visited[start] = True
while queue:
v = queue.popleft()
print(v, end=' ')
for i in graph[v]:
if not visited[i]:
queue.append(i)
visited[i] = True
graph = [[],[2,3,8],[1,7],[1,4,5],[3,5],[3,4],[7],[2,6,8],[1,7]] #1~8 순서대로 인접한 노드 적기
visited = [False] * 9 #노드개수+1
bfs(graph, 1, visited)
[예 - 최단경로 찾기]
- 거리가 0인 개수 : 1. 정답이 아님 → 거리가 0인 개수 : 0
- 거리가 1인 개수 : 2, 5, 6. / 2가 정답이 아님 → 3, 11을 큐에 추가, 거리가 1인 개수 : 2 / 반복...
while len(queue) > 0: #큐에 데이터가 있다면
count = len(queue) #같은 거리에 있는 큐 데이터 개수
for time in range(count): #같은 거리에 있는 큐 개수 만큼 검사
now = queue.pop(0)
if now == dest: #정답이 존재하면 값 반환
return answer
for i in data: #연결된 포인트 완전 탐색
if i[0]==now and visited[i[1]-1]==False: #방문하지 않은 연결된 길이라면 큐에 추가하고 방문 표시
queue.append(i[1])
visited[i[1]-1]=True
elif i[1]==now and visited[i[0]-1]==False:
queue.append(i[0])
visited[i[0]-1]=True
answer += 1 #거리를 1 더 벌림
return answer
DFS (깊이 우선 탐색)
- 거리가 1인 개수 : 2, 5, 6. / 2가 정답이 아님 → 3, 11을 큐에 추가, 거리가 1인 개수 : 2 / 반복...
- 정점의 자식들을 먼저 탐색하는 방식
- 시간 복잡도 : O(V+E)
- 동작 과정
- 탐색 시작 노드를 스택에 삽입하고 방문 처리를 함
- 스택의 최상단 노드에 방문하지 않은 인접 노드가 있으면 그 인접 노드를 스택에 넣고 방문 처리를 함. 방문하지 않은 인접 노드가 없으면 스택에서 최상단 노드를 꺼냄
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복함
def dfs(graph, v, visited):
visited[v] = True
print(v, end=' ')
for i in graph[v]:
if not visited[i]:
dfs(graph, i, visited)
graph = [[],[2,3,8],[1,7],[1,4,5],[3,5],[3,4],[7],[2,6,8],[1,7]] #1~8 순서대로 인접한 노드 적기
visited = [False] * 9 #노드개수+1
dfs(graph, 1, visited)
[예 - 미로 찾기]
- 배열로 선언
- [0,0]에서 흰색으로 갈 수 있는 값 [0,1]을 찾음
- [0,1]에서 흰색으로 갈 수 있는 값 [0,2], [1,1]을 찾음... 반복
stack = [[0,0]]
dest = [5,5]
hori = 6
verti = 6
while len(stack)>0: #스택에 데이터가 있다면
now = stack.pop()
if now == dest: #정답 여부 검사
return True
x = now[1]
y = now[0]
if x-1 > -1: #왼쪽으로 이동할 수 있다면
if maps[y][x-1]==0: #스택에 추가하고 방문 여부를 2로 표시
stack.append([y,x-1])
maps[y][x-1]=2
if x+1 < hori: #오른쪽으로 이동할 수 있다면
if maps[y][x+1]==1:
stack.append([y,x+1])
maps[y][x+1]=2
if y-1 > -1: #위로 이동할 수 있다면
if maps[y-1][x]==1:
stack.append([y-1, x])
maps[y-1][x]=2
if y+1 < verti: #아래로 이동할 수 있다면
if maps[y+1][x]==1:
stack.append([y+1,x])
maps[y+1][x]=2
return False #스택에 데이터가 없으면 False
'두두의 알고리즘 > 공부' 카테고리의 다른 글
[자료구조/알고리즘] 연결 리스트(Linked List), 더블 연결 리스트(Double Linked List), 트라이 구조(Trie) (0) | 2022.06.17 |
---|---|
[자료구조 / 알고리즘] 개념, 연습 방법 (0) | 2022.06.17 |
[알고리즘] 소수의 판별 / 투 포인터 / 구간 합 계산 / 순열과 조합 (0) | 2021.12.22 |
[복잡도] 시간 복잡도 / 공간 복잡도 (0) | 2021.12.21 |
[알고리즘] 그래프 - (서로소 집합 / 최소 신장 트리 / 위상 정렬) (0) | 2021.11.29 |