다익스트라 알고리즘(Dijkstra)은 다이나믹 프로그래밍(DP)과 그리디(Greedy) 알고리즘 기법을 결합하여 특정 출발 노드에서 다른 모든 노드까지의 '가장 짧은 경로(최소 비용)'를 완벽하게 찾아내는 알고리즘입니다. 오늘날 GPS 내비게이션 길 찾기 기능의 근간이 되는 아주 강력하고 대표적인 라우팅 기법입니다.
1. 다익스트라의 작동 원리와 특징
다익스트라는 매 순간 '가장 가까운 노드'를 선택하며 거리를 갱신합니다(Relaxation).
● 우선순위 큐(Priority Queue) : 단순히 배열을 돌며 가장 짧은 거리를 찾으면 O(V²)이 걸리지만, 우선순위 큐(최소 힙)를 사용하면 O(E log V)로 속도가 비약적으로 상승합니다. ● 거리 갱신 (Relaxation) : 현재 노드를 거쳐서 특정 노드로 가는 비용이, 기존에 알고 있던 비용보다 저렴하다면 최소 비용을 갱신합니다. ● 한계점 (음수 간선) : 음수 가중치(비용이 마이너스)를 가진 간선이 존재한다면 알고리즘이 고장납니다. 이 경우 벨만-포드(Bellman-Ford) 알고리즘을 사용해야 합니다.
2. 시간 및 공간 복잡도 분석
구현 방식
시간 복잡도
심층 설명
순차 탐색 (선형 탐색)
O(V²)
매번 방문하지 않은 노드 중에서 '가장 최단 거리가 짧은 노드'를 찾기 위해 모든 노드를 스캔합니다. 노드(V)가 10,000개 이하라면 쓸만하지만 그 이상이면 병목이 옵니다.
우선순위 큐 (최소 힙)
O(E log V)
최단 거리를 가진 노드를 즉각적으로 뽑아내는 최소 힙(Min-Heap)을 사용하면, 노드가 100만 개 단위인 거대한 그래프 처리도 순식간에 끝냅니다.
💡 실무 지식: 자바스크립트에서의 다익스트라 구현
Java(PriorityQueue)나 Python(heapq), C++(std::priority_queue)는 우선순위 큐를 표준 라이브러리로 강력하게 지원하지만, 안타깝게도 JavaScript/TypeScript는 내장된 우선순위 큐(Priority Queue) 자료구조가 없습니다. 실무 알고리즘 테스트 시에는 직접 Min-Heap 클래스를 구현해서 풀거나, 데이터가 크지 않다면 단순 배열 선형 탐색 O(V²)으로 빠르게 제출하는 것이 현실적인 전략입니다.
// JavaScript 구현 (가장 단순한 O(V^2) 방식 - 코딩테스트용)
const graph = {
'A': { 'B': 2, 'C': 5 },
'B': { 'C': 1, 'D': 3 },
'C': { 'D': 6 },
'D': {}
};
function dijkstra(graph, start) {
const distances = {};
const visited = new Set();
// 초기화
for (let node in graph) {
distances[node] = Infinity;
}
distances[start] = 0;
while (true) {
let currNode = null;
let shortestDist = Infinity;
// 방문하지 않은 노드 중 가장 거리가 짧은 노드 탐색 (내장 PQ가 없어서 선형 탐색)
for (let node in distances) {
if (!visited.has(node) && distances[node] < shortestDist) {
shortestDist = distances[node];
currNode = node;
}
}
if (currNode === null) break;
visited.add(currNode);
// 인접 노드 거리 갱신 (Relaxation)
for (let neighbor in graph[currNode]) {
let cost = distances[currNode] + graph[currNode][neighbor];
if (cost < distances[neighbor]) {
distances[neighbor] = cost; // 최단 거리 갱신
}
}
}
return distances;
}
console.log("시작점 A 기준 최단 거리:", dijkstra(graph, 'A'));
// 출력: { A: 0, B: 2, C: 3, D: 5 }