Menu
Coddy logo textTech

Counting Sort

Zuletzt aktualisiert

Counting Sort ist ein vergleichsfreies Sortierverfahren für ganze Zahlen in einem bekannten, begrenzten Bereich. Es zählt, wie oft jeder Wert vorkommt, und nutzt diese Zählungen dann, um jeden Wert direkt an seine sortierte Position zu schreiben - ohne Vergleiche. Drücke oben auf Abspielen, um zu sehen, wie die Werte gezählt und anschließend der Reihe nach platziert werden.

Counting Sort läuft in O(n + k)-Zeit, wobei k der Bereich der Eingabewerte ist. Wenn k nicht viel größer als n ist, ist es extrem schnell und kann O(n log n)-Vergleichssortierungen übertreffen; ist der Wertebereich jedoch riesig, macht das O(k)-Zählarray es unpraktikabel.

Zeit- und Speicherkomplexität

FallKomplexitätAnmerkungen
ZeitO(n + k)n Elemente, k = Wertebereich
SpeicherO(n + k)Zählarray + Ausgabearray
StabilJaWenn von rechts nach links mit Präfixsummen platziert wird
Vergleich?NeinSortiert durch Zählen, nicht durch Vergleichen
Am besten fürKleiner Ganzzahlbereichk nahe an n

Schritt für Schritt

SchrittWas passiert
1Den Maximalwert finden, um das Zählarray zu dimensionieren.
2Zählen, wie oft jeder Wert vorkommt.
3(Optional) Die Zählungen für Stabilität in Präfixsummen umwandeln.
4Jeden Wert so oft in die Ausgabe schreiben, wie er vorkommt.
5Das Ausgabearray ist nun vollständig sortiert.

Durchgerechnetes Beispiel

Sortieren von [1, 4, 1, 2, 4] (die Werte reichen von 0 bis 4, daher hat das Zählarray 5 Plätze):

DurchgangZustandAktion
Eingabe durchlaufencount = [0, 2, 1, 0, 2]Vorkommen zählen: 1 kommt zweimal vor, 2 einmal, 4 zweimal.
Präfixsummencount = [0, 2, 3, 3, 5]Jeder Platz enthält nun, wie viele Werte <= seinem Index sind, was die endgültigen Positionen ergibt.
4 platzierenoutput = [_, _, _, _, 4]Von rechts nach links lesen: count[4] = 5, also geht 4 an Index 4; auf 4 dekrementieren.
2 platzierenoutput = [_, _, 2, _, 4]count[2] = 3, also geht 2 an Index 2; auf 2 dekrementieren.
1 platzierenoutput = [_, 1, 2, _, 4]count[1] = 2, also geht 1 an Index 1; auf 1 dekrementieren.
4 platzierenoutput = [_, 1, 2, 4, 4]count[4] = 4, also geht diese 4 an Index 3; auf 3 dekrementieren.
1 platzierenoutput = [1, 1, 2, 4, 4]count[1] = 1, also geht diese 1 an Index 0. Das Array ist sortiert.

Wann Counting Sort verwenden

Verwenden, wennVermeiden, wenn
Du ganze Zahlen (oder auf Ganzzahlen abbildbare Schlüssel) in einem kleinen, bekannten Bereich sortierst.Der Wertebereich k weit größer ist als die Elementanzahl n.
Du lineare O(n + k)-Zeit brauchst und dir die zusätzlichen Arrays leisten kannst.Der Speicher knapp ist - das Zählarray kostet unabhängig von n stets O(k).
Du eine stabile Sortierung als Unterroutine brauchst (z. B. innerhalb von Radix Sort).Die Schlüssel Fließkommazahlen, Zeichenketten oder beliebige Objekte ohne Ganzzahl-Abbildung sind.
Der Maximalwert beschränkt und im Voraus günstig zu berechnen ist.Der Bereich unbekannt oder unbeschränkt ist, sodass du das Zählarray nicht dimensionieren kannst.

Counting Sort-Code

Eine saubere, lauffähige Counting Sort-Implementierung in Python, JavaScript, Java, C++, C. Wähle eine Sprache, kopiere den Code oder öffne ihn vorgeladen im Coddy-Playground.

Counting Sort-Code in Python

Python
1def counting_sort(a):2    # Works for non-negative integers with a small max value3    counts = [0] * (max(a) + 1)4    for value in a:5        counts[value] += 16    # Prefix sums turn counts into final positions7    for i in range(1, len(counts)):8        counts[i] += counts[i - 1]9    out = [0] * len(a)10    for value in reversed(a):  # reversed keeps equal values stable11        counts[value] -= 112        out[counts[value]] = value13    return out14
15
16nums = [4, 2, 2, 8, 3, 3, 1]17print("Before:", nums)18print("After: ", counting_sort(nums))
Führe diesen Code im Python-Playground aus

Counting Sort FAQ

Was ist die Zeitkomplexität von Counting Sort?
Counting Sort ist O(n + k), wobei n die Anzahl der Elemente und k der Bereich der möglichen Werte ist. Wenn k = O(n) gilt, ist dies lineare Zeit. Es benötigt O(n + k) zusätzlichen Speicher.
Ist Counting Sort stabil?
Das kann es sein. Die stabile Version bildet Präfixsummen der Zählungen und platziert die Elemente von rechts nach links, was die relative Reihenfolge gleicher Schlüssel erhält. Die hier gezeigte einfache Version des "Neuschreibens nach Wert" erzeugt eine korrekte Sortierung, wird aber hauptsächlich für einfache ganze Zahlen verwendet.
Wann sollte ich Counting Sort verwenden?
Verwende es zum Sortieren ganzer Zahlen (oder auf Ganzzahlen abbildbarer Schlüssel) innerhalb eines kleinen, bekannten Bereichs. Wenn der Wertebereich k viel größer als die Anzahl der Elemente ist, verschwendet das Zählarray Speicher und eine Vergleichssortierung ist besser.
Was ist der Unterschied zwischen Counting Sort und Radix Sort?
Counting Sort sortiert in einem einzigen Durchgang nach dem gesamten Wert und benötigt ein Zählarray so groß wie der Wertebereich. Radix Sort sortiert Ziffer für Ziffer und ruft üblicherweise für jede Ziffer ein stabiles Counting Sort auf, was den Bereich pro Durchgang klein hält (z. B. 10 für Dezimalziffern). Radix Sort bewältigt große Wertebereiche, die ein einzelnes Counting Sort unpraktikabel machen würden.
Warum ist Counting Sort nicht immer schneller als Quicksort?
Counting Sort ist O(n + k), gewinnt also nur, wenn der Wertebereich k mit n vergleichbar ist. Ist k riesig - etwa das Sortieren von 100 Werten im Bereich 0 bis 1,000,000,000 - dominiert das O(k)-Zählarray und verschwendet Speicher, während eine O(n log n)-Vergleichssortierung wie Quicksort schnell und speichereffizient bleibt.
Kann Counting Sort mit negativen Zahlen umgehen?
Ja, mit einem kleinen Versatz. Statt das Zählarray direkt über den Wert zu indizieren, indiziere es über value - min, sodass der kleinste Wert auf Index 0 abgebildet wird. Die Größe des Zählarrays wird zu max - min + 1. Diesen Versatz zu vergessen ist ein häufiger Fehler, der bei negativen Eingaben abstürzt.
Coddy programming languages illustration

Meistere Algorithmen mit Coddy

LOS GEHT'S