Menu
Coddy logo textTech

Algorytm Kruskala

Ostatnia aktualizacja

Algorytm Kruskala buduje minimalne drzewo rozpinające (MST), czyli najtańszy zbiór krawędzi łączący wszystkie węzły bez cykli. Sortuje wszystkie krawędzie według wagi, a potem zachłannie dodaje kolejną najtańszą krawędź, o ile łączy dwa węzły, które nie są jeszcze połączone. Kliknij odtwarzanie powyżej i zobacz, jak drzewo rośnie o jedną najtańszą bezpieczną krawędź naraz.

Sprawdzenie "czy już połączone?" wykonuje struktura union-find (zbiory rozłączne): krawędź jest pomijana, jeśli oba jej końce należą już do tej samej składowej, bo jej dodanie utworzyłoby cykl. Koszt zdominowany jest przez sortowanie, co daje łącznie O(E log E). Algorytm Kruskala najlepiej sprawdza się w grafach rzadkich.

Złożoność czasowa i pamięciowa

MiaraZłożonośćUwagi
CzasO(E log E)Zdominowany przez sortowanie krawędzi
Operacje union-find≈ O(E α(V))Prawie stały koszt sprawdzenia dzięki kompresji ścieżek
PamięćO(V + E)Lista krawędzi + struktura zbiorów rozłącznych
Najlepszy dlaGrafów rzadkichDziała na globalnej liście krawędzi

Krok po kroku

KrokCo się dzieje
1Posortuj wszystkie krawędzie rosnąco według wagi.
2Umieść każdy węzeł w osobnej składowej (union-find).
3Weź kolejną najtańszą krawędź.
4Jeśli jej końce są w różnych składowych, dodaj ją do drzewa i połącz składowe.
5W przeciwnym razie pomiń ją (utworzyłaby cykl).
6Zakończ, gdy drzewo ma V − 1 krawędzi.

Przykład krok po kroku

Graf z węzłami A, B, C, D i krawędziami A-B(1), B-C(2), A-C(3), C-D(4), B-D(5). Posortowane krawędzie: A-B(1), B-C(2), A-C(3), C-D(4), B-D(5):

Krawędź (waga)Składowe przedDziałanie
A-B(1){A} {B} {C} {D}Różne składowe: dodaj do MST, połącz w {A,B}.
B-C(2){A,B} {C} {D}Różne składowe: dodaj do MST, połącz w {A,B,C}.
A-C(3){A,B,C} {D}A i C już są razem: pomiń (powstałby cykl).
C-D(4){A,B,C} {D}Różne składowe: dodaj do MST, połącz w {A,B,C,D}.
Stop{A,B,C,D}Drzewo ma V - 1 = 3 krawędzie. MST = A-B, B-C, C-D, łączna waga 7.

Kiedy używać algorytmu Kruskala

Używaj, gdyUnikaj, gdy
Graf jest rzadki (mało krawędzi w stosunku do węzłów).Graf jest gęsty: algorytm Prima z kopcem jest zwykle szybszy.
Krawędzie są dostępne jako globalna lista, którą można posortować.Krawędzie są dostępne tylko przez listy sąsiedztwa, które trzeba przeglądać dla każdego węzła.
Chcesz prostej implementacji opartej na union-find.Potrzebujesz, aby drzewo rosło od konkretnego węzła startowego.
Chcesz zbudować las rozpinający grafu niespójnego.Musisz obsługiwać krawędzie napływające strumieniowo bez pełnego sortowania.

Kruskal's Algorithm: kod

Przejrzysta, gotowa do uruchomienia implementacja algorytmu Kruskal's Algorithm w językach: Python, JavaScript, Java, C++, C. Wybierz język, skopiuj kod albo otwórz go od razu w edytorze online Coddy.

Kruskal's Algorithm: kod (Python)

Python
1def find(parent, x):2    while parent[x] != x:3        parent[x] = parent[parent[x]]  # path compression4        x = parent[x]5    return x6
7
8def kruskal(vertices, edges):9    # Take the cheapest edge that does not close a cycle10    parent = {v: v for v in vertices}11    mst, total = [], 012    for w, u, v in sorted(edges):13        root_u, root_v = find(parent, u), find(parent, v)14        if root_u != root_v:15            parent[root_u] = root_v16            mst.append((u, v, w))17            total += w18    return mst, total19
20
21vertices = ["A", "B", "C", "D", "E"]22edges = [23    (4, "A", "B"), (1, "A", "C"), (3, "B", "C"), (2, "B", "D"),24    (5, "C", "D"), (6, "C", "E"), (7, "D", "E"),25]26
27mst, total = kruskal(vertices, edges)28for u, v, w in mst:29    print(f"{u} - {v} (weight {w})")30print("Total MST weight:", total)
Uruchom ten kod w edytorze Python online

Algorytm Kruskala: najczęstsze pytania

Czym jest minimalne drzewo rozpinające?
Minimalne drzewo rozpinające (MST) spójnego grafu ważonego to podzbiór krawędzi, który łączy wszystkie węzły bez cykli przy najmniejszej możliwej łącznej wadze. Dla V węzłów ma dokładnie V - 1 krawędzi.
Czym różni się algorytm Kruskala od algorytmu Prima?
Oba budują minimalne drzewo rozpinające zachłannie. Algorytm Kruskala sortuje globalnie wszystkie krawędzie i dodaje najtańszą, która nie tworzy cyklu, korzystając z union-find. Algorytm Prima rozbudowuje jedno drzewo od węzła startowego, zawsze dodając najtańszą krawędź wychodzącą z drzewa. Kruskal pasuje do grafów rzadkich, a Prim (z kopcem) do gęstych.
Dlaczego algorytm Kruskala używa union-find?
Przed dodaniem krawędzi algorytm Kruskala musi sprawdzić, czy jej dwa końce są już połączone, bo dodanie takiej krawędzi utworzyłoby cykl. Union-find (zbiory rozłączne) odpowiada na pytanie "czy są w tej samej składowej?" i łączy składowe w prawie stałym zamortyzowanym czasie, co utrzymuje wydajność algorytmu.
Kiedy użyć algorytmu Kruskala zamiast algorytmu Prima?
Wybierz algorytm Kruskala, gdy graf jest rzadki i masz już wszystkie krawędzie jako listę do posortowania: sortowanie O(E log E) jest tanie, gdy E jest małe. Algorytm Prima z kopcem binarnym lub Fibonacciego zwykle wygrywa w gęstych grafach, w których E zbliża się do V², bo nie musi z góry sortować każdej krawędzi.
Czy algorytm Kruskala działa na grafach niespójnych?
Tak. Jeśli graf jest niespójny, algorytm Kruskala po prostu nie osiągnie V - 1 krawędzi i zamiast tego wytworzy minimalny las rozpinający, czyli jedno MST na każdą spójną składową. Wynika to naturalnie z tego, że union-find nigdy nie łączy węzłów, między którymi nie ma ścieżki.
Jaki jest najczęstszy błąd przy implementacji algorytmu Kruskala?
Pominięcie kompresji ścieżek i łączenia według rangi w union-find, co zmienia koszt każdego sprawdzenia połączenia z prawie stałego na prawie liniowy i może zdominować czas działania. Innym częstym błędem jest zapomnienie o faktycznym połączeniu dwóch składowych po dodaniu krawędzi, przez co późniejsze krawędzie mogą tworzyć cykle.
Ilustracja języków programowania w Coddy

Opanuj algorytmy z Coddy

ZACZNIJ