Sortierung in Java zusammenführen

1. Einleitung

In diesem Tutorial sehen wir uns den Merge Sort-Algorithmus und seine Implementierung in Java an .

Die Zusammenführungssortierung ist eine der effizientesten Sortiertechniken und basiert auf dem Paradigma „Teilen und Erobern“.

2. Der Algorithmus

Merge Sort ist ein "Divide and Conquer" -Algorithmus, bei dem wir das Problem zunächst in Teilprobleme unterteilen. 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 mithilfe der Rekursion leicht implementiert werden können, da wir uns eher mit den Teilproblemen als mit dem Hauptproblem befassen.

Der Algorithmus kann als der folgende zweistufige Prozess beschrieben werden:

  • Teilen: In diesem Schritt teilen wir das Eingabearray in zwei Hälften , wobei der Drehpunkt der Mittelpunkt des Arrays ist. Dieser Schritt wird rekursiv für alle halben Arrays ausgeführt, bis keine zu teilenden halben Arrays mehr vorhanden sind.
  • Erobern: In diesem Schritt sortieren und führen wir die geteilten Arrays von unten nach oben zusammen und erhalten das sortierte Array.

Das folgende Diagramm zeigt den vollständigen Zusammenführungssortiervorgang für ein Beispielarray {10, 6, 8, 5, 7, 3, 4}.

Wenn wir uns das Diagramm genauer ansehen, können wir sehen, 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 in Aktion gesetzt und beginnen, Arrays beim Sortieren wieder zusammenzuführen:

3. Implementierung

Für die Implementierung schreiben wir eine mergeSort- Funktion, die das Eingabearray und seine Länge als Parameter berücksichtigt. Dies wird eine rekursive Funktion sein, daher benötigen wir die Basis und die rekursiven Bedingungen.

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

Für den rekursiven Fall erhalten wir den mittleren Index und erstellen zwei temporäre Arrays l [] und r [] . Die mergeSort- 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); }

Wir rufen dann die Zusammenführungsfunktion auf , die die Eingabe und sowohl die Unterarrays als auch den Start- und Endindex beider Unterarrays aufnimmt .

Die Zusammenführungsfunktion vergleicht die Elemente beider Unterarrays nacheinander und platziert das kleinere Element im Eingabearray.

Wenn wir das Ende eines der Unterarrays erreichen, werden die restlichen Elemente des anderen Arrays in das Eingabearray kopiert, wodurch wir das endgültig 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 Unit-Test 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, und der O (n) -Zeit, um das gesamte Array zusammenzuführen.

Wenn gelöst, wird die zeitliche Komplexität zu O (nLogn).

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

Die räumliche Komplexität des Algorithmus ist O (n), da wir bei jedem rekursiven Aufruf temporäre Arrays erstellen.

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir gesehen, wie der Merge-Sortieralgorithmus funktioniert und wie wir ihn in Java implementieren können.

Der gesamte Arbeitscode ist auf GitHub verfügbar.