Algorytm MergeSort w językach C i Java

Ostatnia aktualizacja: 6 marca 2026
  • MergeSort wykorzystuje metodę dziel i zwyciężaj do sortowania rekurencyjnego, co jest wydajne w przypadku dużych zbiorów.
  • Złożoność czasowa: O(n log n), korzystna w porównaniu do algorytmów kwadratowych, takich jak Bubble czy Selection.
  • Rozwiązanie jest stabilne: zachowuje względną kolejność duplikatów, co jest przydatne, gdy początkowa kolejność ma znaczenie.
  • Wymaga dodatkowej pamięci na podmacierz; można ją łączyć z innymi technikami w celu optymalizacji wydajności.
Algorytm MergeSort

Sortowanie danych jest podstawowym zadaniem w programowaniu i analizie algorytmów. Dostępnych jest wiele technik sortowania, a jedną z najskuteczniejszych jest algorytm MergeSort. Algorytm ten wykorzystuje metodę „dziel i zwyciężaj” do rekurencyjnego sortowania listy elementów.

W tym artykule skupimy się na implementacji algorytmu MergeSort w językach programowania C i Java. Przeanalizujemy krok po kroku, jak działa ten algorytm i jak można go wykorzystać we własnych projektach. Omówimy również złożoność czasową MergeSort i porównamy jego wydajność z innymi algorytmami sortowania.

Algorytm MergeSort w językach C i Java

Algorytm MergeSort wykorzystuje strategię „dziel i zwyciężaj” do sortowania listy elementów. Proces ten składa się z trzech głównych etapów: dziel, zwyciężaj i scal. Zobaczmy, jak zaimplementować ten algorytm w językach programowania C i Java.

Implementacja MergeSort w C

Oto implementacja algorytmu MergeSort w języku C:

#include <stdio.h>

void merge(int arr[], int left[], int right[], int left_size, int right_size) {
    int i = 0, j = 0, k = 0;
    
    while (i < left_size && j < right_size) {
        if (left[i] <= right[j]) {
            arr[k] = left[i];
            i++;
        } else {
            arr[k] = right[j];
            j++;
        }
        k++;
    }
    
    while (i < left_size) {
        arr[k] = left[i];
        i++;
        k++;
    }
    
    while (j < right_size) {
        arr[k] = right[j];
        j++;
        k++;
    }
}

void mergeSort(int arr[], int size) {
    if (size < 2) {
        return;
    }
    
    int mid = size / 2;
    int left[mid];
    int right[size - mid];
    
    for (int i = 0; i < mid; i++) {
        left[i] = arr[i];
    }
    
    for (int i = mid; i < size; i++) {
        right[i - mid] = arr[i];
    }
    
    mergeSort(left, mid);
    mergeSort(right, size - mid);
    merge(arr, left, right, mid, size - mid);
}

int main() {
    int arr[] = {9, 5, 2, 7, 1, 8, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    mergeSort(arr, size);
    
    printf("Sorted array: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    
    return 0;
}

W tej implementacji najpierw definiujemy funkcję merge który odpowiada za łączenie dwóch uporządkowanych podtablic w tablicę główną. Następnie funkcja mergeSort rekurencyjnie dzieli tablicę na mniejsze podtablice i sortuje je za pomocą funkcji merge. Na koniec w funkcji main, tworzymy tablicę testową, wywołujemy mergeSort i pokazujemy uporządkowany układ na ekranie.

  Struktury danych i algorytmy: kompletny przewodnik dla programistów

Implementacja MergeSort w Javie

Zobaczmy teraz, jak zaimplementować algorytm MergeSort w Javie:

public class MergeSort {
    public static void merge(int[] arr, int[] left, int[] right) {
        int i = 0, j = 0, k = 0;

        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                arr[k] = left[i];
                i++;
            } else {
                arr[k] = right[j];
                j++;
            }
            k++;
        }

        while (i < left.length) {
            arr[k] = left[i];
            i++;
            k++;
        }

        while (j < right.length) {
            arr[k] = right[j];
            j++;
            k++;
        }
    }

    public static void mergeSort(int[] arr) {
        if (arr.length < 2) {
            return;
        }

        int mid = arr.length / 2;
        int[] left = new int[mid];
        int[] right = new int[arr.length - mid];

        System.arraycopy(arr, 0, left, 0, mid);
        System.arraycopy(arr, mid, right, 0, arr.length - mid);

        mergeSort(left);
        mergeSort(right);
        merge(arr, left, right);
    }

    public static void main(String[] args) {
        int[] arr = {9, 5, 2, 7, 1, 8, 3};

        mergeSort(arr);

        System.out.print("Sorted array: ");
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

W tej implementacji funkcji MergeSort w Javie używamy metod statycznych dla funkcji merge y mergeSort. Funkcja merge wykonuje to samo zadanie, co w implementacji C, a funkcja mergeSort stosuje tę samą logikę dzielenia i łączenia podtablic. Na funkcji main, tworzymy tablicę testową, wywołujemy mergeSort i wyświetlamy posortowaną tablicę w konsoli.

Jaka jest złożoność czasowa algorytmu MergeSort?

Złożoność czasowa algorytmu MergeSort wynosi O(n log n), gdzie „n” oznacza liczbę elementów w tablicy, które mają zostać posortowane. Oznacza to, że czas działania algorytmu zwiększa się proporcjonalnie do iloczynu „n” i logarytmu o podstawie 2 z „n”. Taka złożoność sprawia, że ​​MergeSort jest jednym z najskuteczniejszych algorytmów sortowania, jakie są obecnie dostępne.

Porównanie MergeSort z innymi algorytmami sortowania

MergeSort wyróżnia się wydajnością w sortowaniu danych. W porównaniu z innymi popularnymi algorytmami, takimi jak sortowanie bąbelkowe czy sortowanie przez wybieranie, MergeSort ma znacznie lepszą złożoność czasową. Podczas gdy sortowanie bąbelkowe i sortowanie przez wybieranie mają złożoność czasową O(n^2), sortowanie scalające ma złożoność czasową O(n log n). Oznacza to, że MergeSort jest w stanie przetwarzać duże ilości danych wydajniej i szybciej niż te mniej wydajne algorytmy.

  Algorytm Grovera: przyszłość wyszukiwania i nie tylko

Najczęściej zadawane pytania

1: Dlaczego warto używać MergeSort zamiast innych algorytmów sortowania?

MergeSort jest preferowany od innych algorytmów sortowania ze względu na swoją efektywność i wydajność. Dzięki złożoności czasowej O(n log n) metoda MergeSort umożliwia sortowanie dużych zbiorów danych szybciej i wydajniej niż algorytmy o złożoności kwadratowej, takie jak sortowanie bąbelkowe czy sortowanie przez wybieranie. Ponadto MergeSort jest algorytmem stabilnym, co oznacza, że ​​zachowuje względną kolejność elementów o równych wartościach, co może mieć istotne znaczenie w niektórych kontekstach.

2: Kiedy powinienem używać funkcji MergeSort w swoich projektach?

Możesz rozważyć użycie funkcji MergeSort, gdy musisz wydajnie sortować duże zbiory danych. Jeśli masz nieuporządkowaną listę elementów i chcesz uzyskać posortowaną listę w jak najkrótszym czasie, MergeSort będzie dla Ciebie doskonałym rozwiązaniem. Należy jednak pamiętać, że MergeSort może wymagać więcej pamięci w porównaniu do innych algorytmów sortowania, ponieważ podczas wykonywania tworzy dodatkowe podtablice.

3: Czy są jakieś wady korzystania z funkcji MergeSort?

Potencjalną wadą funkcji MergeSort jest dodatkowe zużycie pamięci. W trakcie wykonywania algorytmu tworzone są dodatkowe podtablice w celu podziału i połączenia danych, co może zwiększyć wymagania dotyczące pamięci, zwłaszcza podczas pracy z bardzo dużymi zbiorami danych. Jednakże w większości przypadków wada ta jest nieistotna w porównaniu do efektywności algorytmu.

4: Czy MergeSort obsługuje duplikaty elementów w tablicy?

Tak, MergeSort radzi sobie z duplikatami elementów w tablicy. Algorytm jest stabilny, co oznacza, że ​​zachowuje względną kolejność elementów o równych wartościach. Jest to ważne, gdy chcesz zachować oryginalną kolejność elementów na wypadek wystąpienia duplikatów. MergeSort zapewnia, że ​​zduplikowane elementy pojawią się w tej samej kolejności względnej zarówno w tablicy wejściowej, jak i w tablicy posortowanej.

  Przykłady drzew binarnych w Javie: kompletny przewodnik

5: Czy istnieją jakieś warianty lub udoskonalenia algorytmu MergeSort?

Tak, istnieje kilka wariantów i udoskonaleń algorytmu MergeSort. Niektóre z tych wariantów obejmują iteracyjne MergeSort, MergeSort z optymalizacją scalania podtablic oraz hybrydowe MergeSort, które łączy MergeSort z innym algorytmem sortowania, takim jak Insertion Sort, w celu osiągnięcia lepszej wydajności w niektórych przypadkach. Celem tych wariantów jest poprawa wydajności i efektywności algorytmu MergeSort w określonych sytuacjach.

6: Gdzie mogę dowiedzieć się więcej na temat MergeSort i innych algorytmów sortowania?

Jeśli chcesz dowiedzieć się więcej na temat MergeSort i innych algorytmów sortowania, zapoznaj się z następującymi materiałami:

Wnioski

W tym artykule przyjrzymy się algorytmowi MergeSort w językach programowania C i Java. Dowiedzieliśmy się, jak wdrożyć ten wydajny algorytm sortowania danych i omówiliśmy jego złożoność czasową. Dzięki szczegółowym przykładom i wyjaśnieniom masz teraz solidną wiedzę na temat działania funkcji MergeSort w językach C i Java oraz wiesz, jak możesz ją zastosować we własnych projektach.

MergeSort to potężne narzędzie do sortowania dużych zbiorów danych, a jego złożoność czasowa na poziomie O(n log n) sprawia, że ​​jest atrakcyjną opcją w porównaniu do innych, mniej wydajnych algorytmów sortowania. Jeśli chcesz sortować dane sprawnie i szybko, rozważ użycie algorytmu MergeSort.

Eksperymentuj z funkcją MergeSort w swoich projektach, aby cieszyć się jej zaletami i optymalną wydajnością sortowania danych!