Menu
Coddy logo textTech

다익스트라 알고리즘

마지막 업데이트

다익스트라 알고리즘은 음이 아닌 간선 가중치를 가진 그래프에서 시작 노드로부터 다른 모든 노드까지의 최단 경로를 찾습니다. 각 노드에 잠정 거리를 유지하고, 잠정 거리가 가장 작은 미확정 노드를 반복적으로 확정하며 그 간선을 완화합니다. 현재 노드를 거치는 더 짧은 경로가 발견될 때마다 이웃 노드의 거리를 갱신합니다. 위의 재생 버튼을 눌러 각 노드가 확정될 때 거리가 낮아지는 모습을 확인하세요.

핵심 아이디어는 탐욕적입니다. 가장 가까운 미확정 노드가 선택되면 그 거리는 최종적입니다. 그 노드로 가는 다른 모든 경로는 이미 더 멀리 있는 노드를 거쳐야 하기 때문입니다. 이진 힙 우선순위 큐를 사용하면 다익스트라는 O((V + E) log V) 시간에 실행됩니다. 음이 아닌 가중치가 필요하며, 간선이 음수일 수 있으면 벨만-포드를 사용하세요.

시간 및 공간 복잡도

구현복잡도비고
이진 힙O((V + E) log V)일반적이고 실용적인 선택
배열 순회O(V²)더 단순함; 밀집 그래프에 적합
공간O(V)거리 + 우선순위 큐
요구 사항음이 아닌 가중치음수 간선은 탐욕적 선택을 깨뜨림

단계별 과정

단계무엇이 일어나는가
1시작 노드의 거리를 0으로, 나머지는 모두 무한대로 설정한다.
2잠정 거리가 가장 작은 미확정 노드를 선택한다.
3그것을 확정으로 표시한다 — 최단 거리가 이제 최종이다.
4각 이웃에 대해 현재-경유-거리 + 간선 가중치를 계산한다.
5그 값이 이웃의 현재 거리보다 작으면 완화한다.
6도달 가능한 모든 노드가 확정될 때까지 반복한다.

풀이 예제

간선 A-B=4, A-C=1, C-B=2, C-D=5, B-D=1 을 가진 그래프에서 시작 노드 A 로부터의 최단 경로:

단계확정거리동작
0-A=0, B=∞, C=∞, D=∞초기화: 시작 노드 A=0, 나머지는 모두 무한대.
1A (0)B=4, C=1, D=∞A 에서 간선 완화: B=4, C=1 로 설정.
2C (1)B=3, D=6C 를 거쳐: B=1+2=3 이 4를 갱신; D=1+5=6.
3B (3)D=4B 를 거쳐: D=3+1=4 가 6을 갱신.
4D (4)A=0, C=1, B=3, D=4D 확정; 완화할 것이 더 없음. 완료.

다익스트라 알고리즘을 사용할 때

사용할 때피해야 할 때
모든 간선 가중치가 음이 아닐 때어떤 간선이든 음수일 수 있을 때: 벨만-포드를 사용
하나의 시작 노드에서 모든 노드까지의 최단 경로가 필요할 때모든 쌍 간 최단 경로가 필요할 때: 플로이드-워셜이 더 단순
그래프가 가중이고 정확한 거리가 필요할 때그래프가 비가중일 때: 단순한 BFS가 더 빠르고 단순
좋은 힙이나 우선순위 큐를 사용할 수 있을 때휴리스틱으로 단일 목적지에 빠르게 도달하고 싶을 때: A* 를 사용

Dijkstra's Algorithm 코드

Python, JavaScript, Java, C++, C로 작성된 깔끔하고 실행 가능한 Dijkstra's Algorithm 구현입니다. 언어를 선택해 코드를 복사하거나 Coddy 플레이그라운드에서 바로 열어보세요.

Python로 구현한 Dijkstra's Algorithm 코드

Python
1import heapq2
3
4def dijkstra(graph, start):5    dist = {node: float("inf") for node in graph}6    dist[start] = 07    pq = [(0, start)]8    while pq:9        d, node = heapq.heappop(pq)10        if d > dist[node]:11            continue  # stale entry, a shorter path was already found12        for neighbor, weight in graph[node]:13            new_dist = d + weight14            if new_dist < dist[neighbor]:15                dist[neighbor] = new_dist16                heapq.heappush(pq, (new_dist, neighbor))17    return dist18
19
20graph = {21    "A": [("B", 4), ("C", 1)],22    "B": [("D", 1)],23    "C": [("B", 2), ("D", 5)],24    "D": [("E", 3)],25    "E": [],26}27
28for node, d in dijkstra(graph, "A").items():29    print(f"A -> {node}: {d}")
이 코드를 Python 플레이그라운드에서 실행하기

다익스트라 알고리즘 자주 묻는 질문

다익스트라 알고리즘의 시간 복잡도는 얼마인가요?
이진 힙 우선순위 큐를 사용하면 O((V + E) log V) 로 실행됩니다. 매 단계 배열을 순회하며 최솟값을 찾는 단순한 버전은 O(V²) 이며, 밀집 그래프에서는 오히려 더 빠를 수 있습니다. 둘 다 O(V) 공간을 사용합니다.
다익스트라는 왜 음수 간선 가중치에서 작동하지 않나요?
다익스트라는 가장 가까운 미확정 노드를 확정하면 그 거리가 최종이라고 가정합니다. 음수 간선은 나중에 이미 확정된 노드로 가는 더 짧은 경로를 만들어 이 가정을 깨뜨릴 수 있습니다. 음수 가중치가 있는 그래프에는 벨만-포드 알고리즘을 사용하세요.
다익스트라와 BFS의 차이는 무엇인가요?
BFS는 간선을 세어(각 간선 가중치가 사실상 1) 단순한 큐로 최단 경로를 찾습니다. 다익스트라는 이를 가중 그래프로 일반화하여 우선순위 큐를 사용해 항상 총거리가 가장 작은 노드를 확장합니다. 비가중 그래프에서는 둘이 같은 경로를 만듭니다.
다익스트라와 A* 탐색의 차이는 무엇인가요?
A* 는 목적지까지 남은 거리를 추정하는 휴리스틱을 더한 다익스트라로, 모든 방향으로 균일하게 퍼지는 대신 탐색을 그 목표로 유도합니다. 휴리스틱이 0이면 A* 는 정확히 다익스트라로 축소됩니다. 단일 목적지와 좋은 허용 휴리스틱이 있으면 A* 를, 모든 노드까지의 거리가 필요하면 다익스트라를 사용하세요.
벨만-포드 대신 다익스트라를 언제 사용해야 하나요?
모든 간선 가중치가 음이 아닐 때는 언제나 다익스트라를 사용하세요. 벨만-포드의 O(V·E) 에 비해 O((V + E) log V) 로 더 빠릅니다. 벨만-포드는 간선이 음수일 수 있거나 음수 사이클을 감지해야 할 때만 선택하세요. 음이 아닌 그래프에서는 다익스트라가 거의 항상 더 나은 선택입니다.
다익스트라는 노드를 확정한 후 다시 방문할 수 있나요?
아니요 — 노드가 일단 확정되면 그 거리는 최종이며 다시는 완화되지 않습니다. 힙 구현에서 흔한 함정은 노드의 거리가 개선된 후 우선순위 큐에 오래된 항목을 남겨두는 것입니다. 꺼낸 노드가 이미 확정되었다면(꺼낸 거리가 기록된 거리를 초과하면) 건너뛰어야 합니다. 이 검사를 잊어도 답은 여전히 정확하지만 불필요한 작업을 낭비합니다.
Coddy programming languages illustration

Coddy로 알고리즘을 마스터하세요

시작하기