Sortierreihenfolge in Java

Sortierung in Java zusammenführen

1. Einführung

In diesem Tutorial sehen wir unsthe Merge Sort algorithm and its implementation in Java an.

Die Sortierung zusammenführen ist eine der effizientesten Sortiertechniken und basiert auf dem Paradigma „Teilen und Erobern“.

2. Der Algorithmus

Merge sort is a “divide and conquer” algorithm wherein we first divide the problem into subproblems. Wenn die Lösungen für die Teilprobleme fertig sind, kombinieren wir sie, um die endgültige Lösung für das Problem zu erhalten.

Dies ist einer der Algorithmen, die einfach mithilfe der Rekursion implementiert werden können, da wir uns eher mit den Unterproblemen als mit dem Hauptproblem befassen.

Der Algorithmus kann wie folgt beschrieben werden:

  • Divide: In this step, we divide the input array into 2 halves, wobei der Drehpunkt der Mittelpunkt des Arrays ist. Dieser Schritt wird für alle Halbarrays rekursiv ausgeführt, bis keine Halbarrays mehr zu teilen sind.

  • Conquer: In this step, we sort and merge the divided arrays von unten nach oben und erhalten das sortierte Array.

Das folgende Diagramm zeigt den vollständigen Sortiervorgang für das Zusammenführen eines Beispiel-Arrays \ {10, 6, 8, 5, 7, 3, 4}.

Wenn wir uns das Diagramm genauer ansehen, sehen wir, dass das Array rekursiv in zwei Hälften geteilt wird, bis die Größe 1 wird. Sobald die Größe 1 wird, werden die Zusammenführungsprozesse aktiv und führen die Arrays beim Sortieren wieder zusammen:

image

3. Implementierung

Für die Implementierung sindwe’ll write a mergeSort function which takes in the input array and its length als Parameter. Dies wird eine rekursive Funktion sein, daher benötigen wir die Basis und die rekursiven Bedingungen.

Die Grundbedingung überprüft, ob die Array-Länge 1 ist, und gibt sie einfach zurück. In den übrigen Fällen wird der rekursive Aufruf ausgeführt.

For the recursive case, we get the middle index and create two temporary arrays l[] and r[]. DiemergeSort-Funktion wird dann für beide Sub-Arrays rekursiv aufgerufen:

public static void mergeSort(int[] a, int n) {
    if (n < 2) {
        return;
    }
    int mid = n / 2;
    int[] l = new int[mid];
    int[] r = new int[n - mid];

    for (int i = 0; i < mid; i++) {
        l[i] = a[i];
    }
    for (int i = mid; i < n; i++) {
        r[i - mid] = a[i];
    }
    mergeSort(l, mid);
    mergeSort(r, n - mid);

    merge(a, l, r, mid, n - mid);
}

We then call the merge function which takes in the input and both the sub-arrays and the starting and end indices of both the sub arrays.

Die Funktionmerge vergleicht die Elemente beider Unterarrays nacheinander und platziert das kleinere Element im Eingabearray.

Wenn wir das Ende eines der Unter-Arrays erreichen, werden die restlichen Elemente des anderen Arrays in das Eingabe-Array kopiert, wodurch wir das endgültige sortierte Array erhalten:

public static void merge(
  int[] a, int[] l, int[] r, int left, int right) {

    int i = 0, j = 0, k = 0;
    while (i < left && j < right) {
        if (l[i] <= r[j]) {
            a[k++] = l[i++];
        }
        else {
            a[k++] = r[j++];
        }
    }
    while (i < left) {
        a[k++] = l[i++];
    }
    while (j < right) {
        a[k++] = r[j++];
    }
}

Der Komponententest für das Programm:

@Test
public void positiveTest() {
    int[] actual = { 5, 1, 6, 2, 3, 4 };
    int[] expected = { 1, 2, 3, 4, 5, 6 };
    MergeSort.mergeSort(actual, actual.length);
    assertArrayEquals(expected, actual);
}

4. Komplexität

Da die Zusammenführungssortierung ein rekursiver Algorithmus ist, kann die Zeitkomplexität als folgende rekursive Beziehung ausgedrückt werden:

T(n) = 2T(n/2) + O(n)

2T(n/2) entspricht der Zeit, die zum Sortieren der Unterarrays erforderlich ist, undO(n) Zeit zum Zusammenführen des gesamten Arrays.

Wenn gelöst,the time complexity will come to O(nLogn).

Dies gilt für den schlechtesten, durchschnittlichen und besten Fall, da das Array immer in zwei geteilt und dann zusammengeführt wird.

Die Speicherplatzkomplexität des Algorithmus beträgtO(n), da bei jedem rekursiven Aufruf temporäre Arrays erstellt werden.

5. Fazit

In diesem kurzen Tutorial haben wir die Funktionsweise des Merge-Sortier-Algorithmus und dessen Implementierung in Java kennengelernt.

Der gesamte Arbeitscode ist inover on GitHub verfügbar.