자료구조·알고리즘 복잡도 정리
탐색·정렬·트리·그래프의 대표 복잡도와 선택 기준을 정리합니다.
복잡도 해석
빅오 표기법은 입력 크기가 커질 때 증가율의 상한을 중심으로 비교합니다. 상수와 낮은 차수 항을 제거하되, 입력 특성과 평균·최악 조건을 함께 확인해야 합니다.
- 이진 탐색은 정렬된 배열에서 O(log n)이다.
- 해시 탐색은 평균 O(1)이지만 충돌에 따라 달라진다.
- 중첩 반복문의 범위가 종속되면 단순히 차수를 곱하지 않는다.
정렬 비교
퀵 정렬은 평균적으로 빠르지만 피벗 분할이 치우치면 최악 O(n²), 병합 정렬은 O(n log n)을 보장하지만 추가 메모리가 필요합니다. 힙 정렬도 O(n log n)을 보장합니다.
- 삽입 정렬은 거의 정렬된 자료에 유리하다.
- 병합 정렬은 안정 정렬이다.
- 선택 정렬은 교환 횟수가 비교적 적다.
트리와 그래프
이진 탐색 트리는 왼쪽이 작고 오른쪽이 큰 순서 관계를 사용합니다. BFS는 큐, DFS는 스택 또는 재귀를 사용하며 최단 경로 조건을 구분해야 합니다.
- 가중치가 없는 그래프의 최소 간선 경로에는 BFS가 적합하다.
- 최소 신장 트리는 모든 정점을 사이클 없이 연결한다.
- 균형이 무너지면 이진 탐색 트리의 탐색이 O(n)이 될 수 있다.
코드에서 연산 횟수를 직접 세는 기준
복잡도는 반복문 개수만 보고 정하지 말고 각 반복문의 실행 범위가 입력 n에 어떻게 의존하는지 합이나 곱으로 계산해야 합니다. 반복 변수가 매번 두 배가 되거나 절반이 되면 로그, 모든 원소 쌍을 비교하면 대체로 제곱 차수가 나타납니다.
- 연속된 반복문은 복잡도를 더하고 중첩된 독립 반복문은 곱한다.
- 재귀식 T(n)=2T(n/2)+n은 병합 정렬처럼 O(n log n)으로 해석된다.
- 그래프 탐색은 인접 리스트 기준 BFS·DFS 모두 O(V+E)이다.
탐욕법·동적계획법·최단경로 구분
탐욕법은 매 단계의 국소 최적 선택이 전체 최적해를 만든다는 성질이 증명될 때 사용하고, 동적계획법은 겹치는 부분 문제와 최적 부분 구조를 이용해 계산 결과를 재사용합니다. 그래프에서는 간선 가중치의 음수 여부에 따라 최단경로 알고리즘을 선택해야 합니다.
- 다익스트라는 음수 가중치 간선이 있으면 일반적으로 사용할 수 없다.
- 벨만-포드는 음수 간선을 처리하고 음수 사이클도 탐지할 수 있다.
- 플로이드-워셜은 모든 정점 쌍 최단경로를 O(V³)에 구한다.
- 백트래킹은 유망하지 않은 선택을 가지치기하고 분할정복은 독립된 부분 문제를 나눠 해결한다.
선형 구조·트리·그래프 연산 완성
자료구조 문제는 저장 형태와 허용 연산을 함께 봅니다. 스택은 한쪽 끝 LIFO, 큐는 삽입과 삭제 끝이 다른 FIFO이며, 트리는 루트·부모·자식·높이 관계, 그래프는 방향·가중치와 표현 방식에 따라 탐색·복잡도가 달라집니다.
- 원형 큐는 front와 rear의 나머지 연산을 사용하며 한 칸을 비우는 구현에서는 포화 조건을 별도로 계산한다.
- 전위는 루트-왼쪽-오른쪽, 중위는 왼쪽-루트-오른쪽, 후위는 왼쪽-오른쪽-루트 순회다.
- AVL 트리는 각 노드의 왼쪽·오른쪽 서브트리 높이 차를 제한하고 회전으로 균형을 복구한다.
- 인접 행렬은 공간 O(V²)로 간선 확인이 빠르고 인접 리스트는 희소 그래프에서 O(V+E) 공간에 유리하다.
- Kruskal은 간선을 가중치 순으로 선택하며 사이클을 막고, Prim은 현재 트리에서 바깥 정점으로 나가는 최소 간선을 확장한다.
시험에 바로 쓰는 비교표
| 구조·알고리즘 | 평균 | 최악 | 필수 조건·특징 |
|---|---|---|---|
| 이진 탐색 | O(log n) | O(log n) | 정렬된 임의 접근 자료 |
| 균형 BST 탐색 | O(log n) | O(log n) | 트리 높이를 로그 수준으로 유지 |
| 일반 BST 탐색 | O(log n) | O(n) | 삽입 순서에 따라 편향 가능 |
| 해시 탐색 | O(1) | O(n) | 충돌 처리와 해시 함수 품질 영향 |
지문 표현을 판단 기준으로 바꾸기
- 왼쪽 키는 작고 오른쪽 키는 크다 → 이진 탐색 트리
- 가중치 없는 최소 간선 경로 → BFS
- 피벗 분할이 한쪽으로 치우친다 → 퀵 정렬 최악 O(n²)
직접 풀어보는 예제와 단계별 해설
탐색 이름을 외우는 대신 검색 구간과 큐가 어떻게 바뀌는지 추적합니다. 아래 배열·그래프·코드는 정처LAB 자체 예제입니다.
없는 값을 이진 탐색하면 어디에서 멈출까?
오름차순 배열에서 20을 찾습니다. 인덱스는 0부터 시작하고 low와 high를 모두 포함하는 구간을 사용합니다. 중앙값 비교 횟수와 최종 반환값을 구하세요.
Python 3
def find(values, target):
low, high = 0, len(values) - 1
while low <= high:
mid = (low + high) // 2
print(low, high, mid, values[mid])
if values[mid] == target:
return mid
if values[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
print(find([3, 8, 12, 17, 23, 29, 34], 20))넓은 표는 좌우로 밀어 나머지 열을 볼 수 있습니다.
| 비교 | 중앙 원소 | 남는 인덱스 구간 |
|---|---|---|
| 1 | 17 < 20 | 4–6 |
| 2 | 29 > 20 | 4–4 |
| 3 | 23 > 20 | low=4, high=3 → 빈 구간 |
풀이 순서
- 17보다 큰 쪽만 남긴 뒤 29보다 작은 쪽을 남기면 인덱스 4 하나만 남습니다. 그 원소 23도 20이 아니므로 마지막 후보를 제외합니다.
- 중앙 원소를 세 번 확인한 후 low > high가 되어 -1을 반환합니다. -1은 배열 원소가 아니라 이 함수가 정한 실패 표시입니다. 20을 정렬 순서대로 삽입할 위치 4와도 다릅니다.
- 검색값만 23으로 바꾸면 같은 세 중앙 원소를 거쳐 인덱스 4를 반환합니다. 마지막 단일 원소 구간도 검사해야 하므로 이 코드에서 while low < high로 바꾸면 23을 놓칩니다.
확인 결과
0 6 3 17
4 6 5 29
4 4 4 23
-1틀리기 쉬운 지점: 정렬 여부, 끝 인덱스 포함 여부, 반환값이 위치인지 원소 값인지 먼저 구별하세요. 로그 복잡도라는 말만으로 특정 입력의 정확한 비교 횟수가 정해지지는 않습니다.
BFS의 방문 순서와 최단 경로는 같은 목록이 아니다
무방향·무가중치 그래프에서 A부터 탐색합니다. 인접 정점은 알파벳 순서로 확인하며 큐에 넣을 때 방문 처리합니다. F까지 최소 간선 수와 경로를 구하세요.
Python 3
from collections import deque
graph = {
'A': ['B', 'C'], 'B': ['A', 'D'],
'C': ['A', 'E'], 'D': ['B', 'E'],
'E': ['C', 'D', 'F'], 'F': ['E']
}
queue = deque(['A'])
parent = {'A': None}
order = []
while queue:
current = queue.popleft()
order.append(current)
for neighbor in graph[current]:
if neighbor not in parent:
parent[neighbor] = current
queue.append(neighbor)
path = []
current = 'F'
while current is not None:
path.append(current)
current = parent[current]
print(' '.join(order))
print(' -> '.join(reversed(path)))
print(len(path) - 1)넓은 표는 좌우로 밀어 나머지 열을 볼 수 있습니다.
| 꺼낸 정점 | 큐 (앞 → 뒤) | 새로 기록한 부모 |
|---|---|---|
| A | B, C | B←A, C←A |
| B | C, D | D←B |
| C | D, E | E←C |
| D | E | 없음: E는 이미 큐에 있음 |
| E | F | F←E |
| F | 비어 있음 | 없음 |
풀이 순서
- 방문 순서는 A B C D E F이지만 B와 C 사이에는 간선이 없습니다. 방문 목록을 그대로 이어 붙여 경로라고 할 수 없습니다.
- F의 부모 E, E의 부모 C, C의 부모 A를 거꾸로 따라가면 A → C → E → F입니다. 정점 4개를 잇는 간선은 3개입니다.
- BFS는 거리가 같은 층을 먼저 처리합니다. 이웃 순서를 바꾸면 같은 길이의 경로 선택은 달라질 수 있지만 최소 간선 수는 같습니다. 간선 비용이 제각각이면 최소 간선 경로와 최소 비용 경로는 다를 수 있습니다.
확인 결과
A B C D E F
A -> C -> E -> F
3틀리기 쉬운 지점: 큐에서 꺼낼 때까지 방문 표시를 미루면 한 정점이 여러 번 큐에 들어갈 수 있습니다. 이 예제는 삽입 시 부모를 기록하여 중복 삽입을 막습니다.
검증 방법과 참고 문서
게시한 Python 코드를 실제 실행하고, 별도 탐색으로 구간·큐·부모와 경로 길이를 대조합니다. 비어 있는 배열, 끝 원소, 단일 원소 구간도 검사합니다.
예제·데이터·풀이표: 정처LAB 자체 설계 · AI 보조 작성 및 로컬 검증 · 예제 수정일 2026-09-27
혼동하기 쉬운 지점
- 퀵 정렬의 최악 복잡도를 O(n log n)으로 단정
- BFS와 DFS의 자료구조를 반대로 암기
- 안정 정렬과 제자리 정렬을 같은 개념으로 판단
개념을 확인했다면 관련 문제에 적용해보세요.
첫 관련 문제 풀기