Counting sort – Zählende Sortierung in Java

Sortieralgorithmen werden verwendet, um die Elemente eines Arrays oder einer Liste in aufsteigender oder absteigender numerischer oder lexikografischer Reihenfolge neu zu ordnen. Die Sortierung ist sehr wichtig für die optimale Leistung anderer Algorithmen, die sortierte Eingabedaten benötigen. Es gibt eine Reihe von verschiedenen Sortieralgorithmen. Die Auswahl eines geeigneten Algorithmus hängt von Faktoren wie der Größe und den Eigenschaften der Eingabedaten, dem verfügbaren Speicher und den Zeit- und Platzanforderungen ab. Um dir die Auswahl zu erleichtern, werden wir in unserer Serie die bekanntesten Datensortieralgorithmen nacheinander vorstellen, ihre Prinzipien, Vor- und Nachteile erklären und sie in Java programmieren. Heute befassen wir uns mit der zählenden Sortierung. Bislang haben wir die folgenden Sortieralgorithmen behandelt:

Zählende Sortierung - counting sort
Zählende Sortierung - counting sort

In diesem Artikel erfährst du:

    Counting sort

    Bisher haben wir Algorithmen besprochen, die Elemente miteinander vergleichen und auf dieser Grundlage eine sortierte Ausgabe erzeugen. Heute stellen wir den ersten Algorithmus vor, der keinen Vergleich in seiner Grundlage verwendet. Counting Sort ist ein ganzzahliger stabiler Sortieralgorithmus, der auf dem Zählen von Objekten mit unterschiedlichen Schlüsselwerten basiert, aus denen die Position in der Ausgabereihenfolge bestimmt wird. Er ist nur in Situationen geeignet, in denen die Varianz der maximalen und minimalen Schlüsselwerte im Vergleich zur Anzahl der Elemente in der Eingabe relativ klein ist. Dieser Algorithmus wird oft als Hilfsroutine in der Radix-Varianteverwendet.

    Counting sort Algoritmus – Funktionsprinzip

    Der Zählsortieralgorithmus ist geeignet, wenn wir viele Elemente mit ganzzahligen Schlüsseln haben, die sich idealerweise in einem relativ kleinen Bereich (max – min) wiederholen. Dann können wir diesen relativ effizienten Algorithmus zum Sortieren der Eingabeelemente verwenden. Er arbeitet nach dem Prinzip des Zählens des Auftretens jedes Schlüssels, den er in einem Hilfsarray speichert. Dieses wird dann in ein Array mit Indizes umgewandelt, die die Positionen der einzelnen Elemente enthalten. Es wird dann verwendet, um die Elemente aus dem Eingabevektor auf den Ausgabevektor abzubilden. Das Funktionsprinzip des Algorithmus lässt sich am besten anhand eines praktischen Beispiels in Java verstehen, das wir implementieren werden.

    Vorteile des Counting sort Algorithmus.

    • Einfach zu implementieren,
    • Schnell und effizient, wenn der Wertebereich 𝑘 k im Vergleich zur Anzahl der Elemente im Eingang 𝑛 n klein ist.
    • stabil.

    Nachteile des Counting sort Algorithmus

    • Funktioniert nur für Schlüssel mit ganzzahligen Werten,
    • Ineffizient bei einem großen Wertebereich.

    Counting sort Zeitintensität

    Algorithmus Methode Zeitliche Komplexität Speicher Stabil
    schlechteste durchschnittlich beste
    Counting sort Zählen O(n+k) O(n+k) O(n+k) O(k) Ja

    Die Variable k ist die Anzahl der Elemente des zählenden Hilfsarrays, mathematisch k = (Maximum – Minimum + 1). Da wir über das Eingabe-Array der Elemente iterieren, erhalten wir eine zeitliche Komplexität von O(n). Die Iteration über das Hilfs-Array trägt zu einer Komplexität von O(k) bei, so dass die gesamte zeitliche Komplexität insgesamt O(n+k) beträgt. Die Speicherung von k Elementen im Hilfsarray im Speicher führt zu einer räumlichen Komplexität von O(k).

    Counting sort Animation, Visualisierung, gif

    Die Visualisierung von Counting sort sieht wie folgt aus:

    counting sort Visualisierung
    SimonWaldherr, CC BY-SA 4.0, via Wikimedia Commons

    Quelle : https://commons.wikimedia.org/wiki/Category:Animations_of_sort_algorithms

    Eine Animation des Counting Sort Algorithmus finden du zum Beispiel auf diese Seite.

    Counting sort Java-Implementierung

    Jetzt zeigen wir eine einfache Implementierung des Counting Sort-Algorithmus in Java.

    CountingSort.java

    package sorting;
    
    public class CountingSort {
        private int min, max;
    
        public void sort(int data[])
        {
            // Don't sort if there are no elements
            if(data.length == 0)
                return;
    
            // Create ouput array
            int[] output = new int[data.length];
    
            // Find min and max value in 1 loop
            min = data[0];
            max = data[0];
            for (int i = 1; i < data.length; i++) {
                if (data[i] < min) {
                    min = data[i];
                } else if (data[i] > max) {
                    max = data[i];
                }
            }
    
            // Create count array
            int k = max - min + 1;
            int[] count = new int[k];
            System.out.println("min = " + min + ", max = " + max +
                    ", size (n) = " + data.length + ", range (k) = " + k);
    
            // Count occurrences of elements
            for (int i = 0; i < data.length; i++) {
                count[data[i] - min]++;
            }
            System.out.print("Count array: ");
            printArray(count);
    
            // Transform counts to positions
            for (int i = 1; i < count.length; i++) {
                count[i] += count[i - 1];
            }
            System.out.print("Transformed count array: ");
            printArray(count);
    
            // Map the elements from input to output based on count indexes
            // Do it backwards
            for (int i = data.length - 1; i >= 0; i--) {
                output[count[data[i] - min] - 1] = data[i];
                count[data[i] - min]--;
            }
    
            // Copy the elements from output back to original array
            for (int i = 0; i < data.length; i++) {
                data[i] = output[i];
            }
        }
    
        // Function to print an array
        public void printArray(int data[])
        {
            for (int i = 0; i < data.length; i++)
                System.out.print(data[i] + " ");
            System.out.println();
        }
    }

    Der Algorithmus besteht aus den folgenden Schritten, die wir kurz erläutern werden:

    Leeres Feld prüfen

    Wenn das Feld leer ist, gibt es nichts zu sortieren.

    Ermitteln der Minimal- und Maximalwerte

    Zistime rozsah hodnôt min a max.

    Erstellen und Initialisieren eines Zählarrays

    Die Größe des Zählfelds ist die Differenz zwischen dem Höchst- und dem Mindestwert plus eins, um den gesamten Wertebereich abzudecken.

    Transformation in akkumulierte Summen

    Für jedes Element im Eingabefeld wird der Wert am entsprechenden Index im Zählfeld um eins erhöht.

    Umwandlung in kumulierte Zählungen

    Jedes Element in der Zählmatrix wird durch die Summe aller vorherigen Werte aktualisiert, wodurch die endgültigen Positionen der Elemente in der Ausgangsmatrix bestimmt werden.

    Platzierung der Elemente im Ausgabefeld

    Das Eingabe-Array wird rückwärts durchlaufen (um Stabilität zu gewährleisten) und die Elemente werden auf der Grundlage der Werte im Zähl-Array im Ausgabe-Array platziert, wobei der Index des Zähl-Arrays nach jeder Platzierung eines Elements um 1 verringert wird.

    Kopieren der Ausgabe zurück in das ursprüngliche Array

    Die sortierten Elemente aus dem Ausgabefeld werden zurück in das ursprüngliche Feld kopiert.

    Main.java

    import sorting.CountingSort;
    
    public class Main {
        public static void main(String[] args) {
            int dataToSort[] = { 4, 2, 4, 2, 1, 1, 1, 7, 6, 3, 5, 5 };
            CountingSort countingSort = new CountingSort();
            System.out.print("Input: ");
            countingSort.printArray(dataToSort);
            countingSort.sort(dataToSort);
            System.out.print("Sorted: ");
            countingSort.printArray(dataToSort);
        }
    }

    Die Ausgabe dieses Beispiels ist:

    Ausgabe des Counting sort Beispiels

    Counting sort – Java-Code

    Wir haben die Dateien mit dem obigen Beispiel in Form von Code vorbereitet, den du direkt in Java ausführen kannst. Lade den Java Counting Sort Code herunter.

    Wenn du ein Java Programmierer bist und nach Arbeit suchst, schau dir unsere Mitareiterbenefits an und reagiere auf die neuesten Stellenangebote.

    Über den Autor

    Jozef Wagner

    Leitender Java-Entwickler

    Ich programmiere seit mehr als 10 Jahren in Java, arbeite derzeit bei msg life Slovakia als leitender Java-Programmierer und helfe Kunden bei der Umsetzung ihrer Anforderungen in die Versicherungssoftware Life Factory. In meiner Freizeit entspanne ich gerne in den Bergen oder spiele ein gutes Computerspiel.

    Informieren Sie uns über sich