그래프란
그래프 자료구조는 노드(정점)와 간선(엣지)으로 이루어진 데이터 구조이다
- 노드(정점): 그래프에서 데이터가 저장되는 기본 단위. 예를 들어, 사람의 관계를 나타내는 그래프에서는 각 사람이 노드 이다.
- 간선(엣지): 노드와 노드를 연결하는 선. 간선은 방향성이 있을 수도 있고 없을 수도 있다. 예를 들어, 두 사람이 친구라면 이를 연결하는 간선이 있다.
그래프의 종류
| 방향그래프 | 설명 |
![]() |
간선에 방향이 있는 그래프이다. 예를 들어, A → B는 A에서 B로 가는 방향만 가능하다. |
| 무방향그래프 | 설명 |
![]() |
간선에 방향이 없는 그래프이다. A와 B가 연결되어 있으면 양방향으로 이동할 수 있다. |
| 가중그래프 | 설명 |
![]() |
간선마다 특정 **가중치(값)**가 부여된 그래프이다. 예를 들어, 도시 간 거리가 간선의 가중치로 표시될 수 있다. |
| 비가중그래프 | 설명 |
![]() |
간선에 가중치가 없는 그래프이다. 모든 간선은 같은 값으로 간주된다. |
| 사이클릭 | 설명 |
![]() |
**사이클(순환)**이 존재하는 그래프이다. 특정 노드에서 시작해 다시 그 노드로 돌아오는 경로가 있다. |
| 에이사이클릭 | 설명 |
![]() |
**사이클(순환)**이 없는 그래프이다. 어떤 노드에서도 다시 원래 노드로 돌아오는 경로가 없다. |
| 트리 | 설명 |
![]() |
하나의 루트 노드를 중심으로 계층 구조를 이루는 에이사이클릭 무방향 그래프이다. 모든 노드가 단 하나의 부모를 가지며, 루트부터 시작해 잎(Leaf)까지 연결된다. |
| 포레스트 | 설명 |
![]() |
트리의 집합으로, 여러 개의 독립된 트리로 구성된 그래프이다. 에이사이클릭 무방향 그래프이며, 서로 연결되지 않은 트리들로 이루어져 있다. |
그래프를 표현하는 방법

인접행렬
행렬 형태로 노드 간 연결 관계를 표시
행과 열이 노드를 나타내며, 간선이 있으면 1, 없으면 0으로 표시함. (가중치가 있을 경우 가중치로 표기)
탐색에 O(1) 밖에 안 걸리나, 메모리를 차지함
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 0 |
| 2 | 1 | 0 | 0 | 1 |
| 3 | 1 | 0 | 0 | 1 |
| 4 | 0 | 1 | 1 | 0 |
인접리스트
각 노드에 연결된 노드들을 리스트로 저장 (가중치 있을 경우 추가 표기)
메모리는 효율적이나 탐색에 O(N - 노드갯수)이 걸림
1: [2, 3]
2: [1, 4]
3: [1, 4]
4: [2, 3]
간선리스트
간선을 리스트 형태로 저장
각 간선은 연결된 두 노드를 나타냄. (가중치 있을 경우 추가 표기)
메모리는 효율적이나 탐색에 O(N - 간선갯수)이 걸림
[(1, 2), (1, 3), (2, 4), (3, 4)]
DFS, BFS 탐색

DFS Depth-First Search (깊이우선탐색)
- 그래프에서 한 경로를 가능한 멀리 끝까지 탐색한 후, 더 이상 갈 곳이 없으면 뒤로 돌아가며 탐색하는 방식이다.
- 스택(재귀 호출 또는 명시적 스택 자료구조)을 활용하여 경로를 관리한다.
탐색 과정
1->2->5->6->3->4->7
스택에서 빼는 순간 방문처리 후 그 아이템의 자식을 스택에 추가 *굵은글씨는 추가, 취소선은 삭제를 나타냄*
취소선 처리일 때 방문처리됨
| 4(1의 자식) | ||||||
| 4 (1의 자식) | 3(1의 자식) | 4 (1의 자식) | ||||
| 3 (1의 자식) | 6(2의자식) | 3 (1의 자식) | 4 (1의 자식) | 7 (4의 자식) | ||
BFS Breadth-First Search (넓이우선탐색)
- 그래프에서 시작 노드부터 가까운 노드들을 먼저 탐색한 후, 점차 멀리 있는 노드를 탐색하는 방식이다.
- 큐를 이용하여 탐색할 노드의 순서를 관리한다.
탐색 과정
1->(1로 인한 2,3,4)->(3통과)->(4통과)->(2로 인한 5,6)->(5통과)->(4으로 인한 7)
큐에다 넣는 순간 방문처리 후, 빼는 순간 그 아이템의 자식들을 큐에 추가 *굵은글씨는 추가, 취소선은 삭제를 나타냄*
굵은글씨 일때 방문처리 됨
| 6 (2의자식) | |||||||
| 5 (2의자식) | 6 (2의자식) | 7 (4의자식) | |||||
| 4 (1의자식) | 4 (1의자식) | 5 (2의자식) | 6 (2의자식) | 7 (4의자식) | |||
| 3 (1의자식) | 3 (1의자식) | 4 (1의자식) | 5 (2의자식) | 6 (2의자식) | 7 (4의자식) | ||
| 2 (1의자식) |
BFS / DFS 관련 백준 문제
https://www.acmicpc.net/problem/1260
n, lines, start = map(int, input().split())
graph = [[0] * (n + 1) for _ in range(n + 1)]
for _ in range(lines):
e1, e2 = map(int,input().split())
graph[e1][e2] = graph[e2][e1] = 1
visited_recur = [0 for _ in range(n + 1)]
visited_dfs = [0 for _ in range(n + 1)]
visited_bfs = [0 for _ in range(n + 1)]
result1 = []
def dfs_recur(v):
visited_recur[v] = 1
# 여기서 방문체크
result1.append(v)
for i in range(1, n+1):
if(graph[v][i] != 0 and visited_recur[i] == 0):
dfs_recur(i)
def dfs_stack(v):
result = []
stk = []
stk.append(v)
while len(stk) > 0:
n_idx = stk.pop(0)
if(visited_dfs[n_idx] == 0):
visited_dfs[n_idx] = 1
result.append(n_idx)
for i in range(n, 0, -1):
if(graph[n_idx][i] != 0 and visited_dfs[i] == 0):
stk.insert(0, i)
return result
def bfs_stack(v):
result = [v]
que = []
que.append(v)
visited_bfs[v] = 1
while len(que) > 0:
n_idx = que.pop(0)
# 왼쪽에서부터 탐색해서 쌓도록 거꾸로가야함
for i in range(1, n+1):
if(graph[n_idx][i] != 0 and visited_bfs[i] == 0):
que.append(i)
visited_bfs[i] = 1
result.append(i)
return result
#dfs_recur(start)
print(' '.join(map(str,dfs_stack(start))))
print(' '.join(map(str,bfs_stack(start))))
일단 아래와 같이 구현하긴 했으나 dfs를 스택으로 구현 한 건은 뭔가 코드가 직관적이지가 않다..
스택에 불필요하게 스킵될만한 아이들도 들어가야하고, 웬만하면 dfs는 재귀로 짤 수 있음 짜는게 좋을 것 같다.. ㅠ
'알고리즘' 카테고리의 다른 글
| [항해 99 챌린지] N-queen 문제 (1) | 2024.11.25 |
|---|---|
| [99클럽/코딩테스트 챌린지] 퀵 정렬, 합병정렬 (2) | 2024.11.23 |
| [99클럽 코테 스터디] [leetcode] 선물이 가장 많은 꾸러미로부터 선물 가져오기 (1) | 2024.11.18 |
| [99클럽/코딩테스트 챌린지] [프로그래머스] 다리를 지나는 트럭 (0) | 2024.11.15 |
| [백준] 26042 식당 입구 대기 줄 (0) | 2024.11.15 |






