Menu
Coddy logo textTech

프림 알고리즘

마지막 업데이트

프림 알고리즘은 최소 신장 트리(MST) - 모든 노드를 사이클 없이 연결하는 가장 저렴한 간선 집합 - 를 시작 노드에서 하나의 트리를 바깥쪽으로 키우며 구성합니다. 각 단계에서 트리에서 트리 바깥의 노드로 교차하는 모든 간선을 살펴보고 가장 저렴한 것을 추가합니다. 위의 재생을 눌러 항상 새 노드에 도달하는 최소 가중치 간선을 택하며 트리가 확장되는 모습을 확인하세요.

항상 최소 교차 간선을 선택하기 때문에 각 추가는 안전합니다(어떤 MST의 일부임이 보장됩니다). 각 바깥 노드로 가는 가장 저렴한 간선을 키로 하는 이진 힙 우선순위 큐를 사용하면 프림은 O(E log V)에 실행됩니다. 이는 하나의 연결된 트리를 키우는 대신 모든 간선을 전역적으로 정렬하는 크루스칼과 대조됩니다.

시간 및 공간 복잡도

구현복잡도비고
이진 힙O(E log V)교차 간선의 우선순위 큐
인접 행렬O(V²)더 단순함; 밀집 그래프에 적합
공간O(V + E)트리 소속 + 우선순위 큐
가장 적합한 경우밀집 그래프단일 시작 노드에서 성장

단계별 설명

단계무슨 일이 일어나는가
1아무 단일 노드로 트리를 시작한다.
2트리에서 트리 바깥의 노드로 교차하는 모든 간선을 살펴본다.
3가중치가 가장 작은 교차 간선을 선택한다.
4그 간선과 새 노드를 트리에 추가한다.
5모든 노드가 트리에 들어올 때까지 반복한다.

풀이 예제

간선 A-B=1, A-C=3, B-C=2, B-D=4, C-D=5 를 가진 4개 노드 그래프의 MST를 A 에서 시작해 구성:

단계트리교차 간선선택된 간선
1{A}A-B=1, A-C=3A-B (가중치 1)
2{A, B}A-C=3, B-C=2, B-D=4B-C (가중치 2)
3{A, B, C}B-D=4, C-D=5B-D (가중치 4)
4{A, B, C, D}없음 - 모든 노드가 트리에 있음완료: MST 가중치 1+2+4 = 7

프림 알고리즘을 사용할 때

사용할 때피할 때
연결된 무방향 가중 그래프의 최소 신장 트리가 필요할 때.그래프가 방향성이 있거나 최단 경로가 필요할 때 - 대신 다익스트라나 벨만-포드를 사용한다.
그래프가 밀집(E 에 가까움)할 때; O(V²) 행렬 형태가 단순하고 빠르다.그래프가 희소하고 간선이 이미 정렬되어 있거나 정렬하기 쉬울 때 - 크루스칼이 더 단순한 경우가 많다.
트리를 한 영역에서 바깥쪽으로 키우고 싶을 때(예: 점진적 네트워크 배치).그래프가 비연결일 때 - 프림은 하나의 성분만 신장하므로 최소 신장 숲이 필요하다.
이미 인접 구조와 우선순위 큐를 사용할 수 있을 때.전역 간선 집합에서 사이클을 감지해야 할 때 - union-find(크루스칼)가 이 형태에 더 잘 맞는다.

Prim's Algorithm 코드

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

Python로 구현한 Prim's Algorithm 코드

Python
1import heapq2
3
4def prim(graph, start):5    visited = {start}6    heap = [(w, start, v) for v, w in graph[start]]7    heapq.heapify(heap)8    mst, total = [], 09    while heap and len(visited) < len(graph):10        w, u, v = heapq.heappop(heap)11        if v in visited:12            continue13        visited.add(v)14        mst.append((u, v, w))15        total += w16        # Offer the new node's edges to the frontier17        for neighbor, weight in graph[v]:18            if neighbor not in visited:19                heapq.heappush(heap, (weight, v, neighbor))20    return mst, total21
22
23graph = {24    "A": [("B", 4), ("C", 1)],25    "B": [("A", 4), ("C", 3), ("D", 2)],26    "C": [("A", 1), ("B", 3), ("D", 5)],27    "D": [("B", 2), ("C", 5), ("E", 7)],28    "E": [("D", 7)],29}30
31mst, total = prim(graph, "A")32for u, v, w in mst:33    print(f"{u} - {v} (weight {w})")34print("Total MST weight:", total)
이 코드를 Python 플레이그라운드에서 실행하기

프림 알고리즘 FAQ

프림 알고리즘의 시간 복잡도는 얼마인가요?
이진 힙 우선순위 큐를 사용하면 프림은 O(E log V)에 실행됩니다. 각 단계에서 최소 교차 간선을 훑는 더 단순한 인접 행렬 버전은 O(V²)이며, 밀집 그래프에서는 더 빠를 수 있습니다. 둘 다 O(V + E) 공간을 사용합니다.
프림 알고리즘과 크루스칼 알고리즘의 차이는 무엇인가요?
둘 다 탐욕적으로 최소 신장 트리를 찾습니다. 프림은 시작 노드에서 하나의 연결된 트리를 키우며, 트리를 떠나는 가장 저렴한 간선을 (우선순위 큐를 사용해) 반복적으로 추가합니다. 크루스칼은 가중치로 정렬된 모든 간선을 고려하고, 사이클을 만들지 않는 가장 저렴한 간선을 (union-find를 사용해) 추가합니다. 프림은 밀집 그래프에서, 크루스칼은 희소 그래프에서 흔히 선호됩니다.
프림 알고리즘은 항상 최적의 MST를 찾나요?
네. 각 단계에서 현재 트리를 교차하는 가장 저렴한 간선은 추가해도 안전합니다 - 그것은 어떤 최소 신장 트리에 속합니다(컷 성질). 안전한 간선을 반복적으로 추가하면 그래프가 연결되어 있는 한 진정한 최소 신장 트리가 만들어집니다.
크루스칼 대신 프림 알고리즘을 언제 사용해야 하나요?
그래프가 밀집할 때 프림을 선택하세요. O(V²) 행렬 형태는 모든 E 개의 간선을 정렬할 필요가 없고 시작 노드에서 하나의 트리를 키우기 때문입니다. 크루스칼은 간선 리스트 정렬이 저렴하고 union-find가 사이클 검사를 빠르게 유지하는 희소 그래프에서 빛을 발합니다. 둘 다 올바른 MST를 생성하므로 선택은 주로 간선 밀도와 이미 갖고 있는 자료 구조에 달려 있습니다.
시작 노드가 결과 MST에 영향을 주나요?
아니요 - 연결 그래프의 최소 신장 트리 가중치는 유일하므로, 어느 노드에서 시작하든 MST의 총 가중치는 같습니다. 구체적인 간선은 여러 간선이 같은 가중치를 가지고 여러 MST가 존재할 때만 달라질 수 있습니다. 그 외에는 프림이 시작 노드와 관계없이 정확히 같은 트리에 도달합니다.
프림 알고리즘은 비연결 그래프를 처리할 수 있나요?
직접적으로는 아닙니다. 프림은 하나의 트리를 키우므로 시작 노드가 포함된 연결 성분만 신장하고 나머지는 건드리지 않습니다. 각 성분을 덮으려면 방문하지 않은 노드에서 프림을 반복 실행하여 하나의 트리가 아니라 최소 신장 숲을 생성하게 됩니다.
Coddy programming languages illustration

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

시작하기