There's an in-place (MSB) radix sort.
Es geht ungefähr so:
- beginnt mit dem ersten Bit.
Verschieben Sie alle Elemente mit diesem Bit gleich 0 nach links und alle diejenigen mit diesem Bit gleich 1 auf der rechten Seite.
Sie tun dies ähnlich wie Quicksort, indem Sie von beiden Seiten in die Mitte gehen und 1 auf der linken Seite mit 0 auf der rechten Seite tauschen.
- Recurse auf der linken Seite und der rechten Seite unter Berücksichtigung des nächsten Bits.
Der Prozess geht ungefähr so:
↓ ↓
0... 1...
--------------- ---------------
↓ ↓ ↓ ↓
00... 01... 10... 11...
------- ------- ------- -------
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
000 001 010 011 101 110 110 111
--- --- --- --- --- --- --- ---
...
Die Zeitkomplexität ist O(bits*n)
und der Raum Komplexität ist O(bits)
.
Also mit einer konstanten Anzahl von Bits ist die Komplexität der Zeit O(n)
und die Raumkomplexität ist O(1)
.
Es ist auch möglich, dies mit Countingsort zu tun (mit der gleichen Zeit und Raum Komplexität).
- Zählen Sie, wie viele von jedem Element es gibt.
- Mit diesem können Sie bestimmen, wo im Array diese Elemente angezeigt werden sollen.
Erstellen Sie eine Nachschlagetabelle (Zuordnungsindex zum Offset, kann ein Array sein), der alle oben genannten Startpunkte enthält, die verwendet werden, um zu bestimmen, wohin das nächste Element gehen soll.
Jetzt durchlaufen Sie das Array und tauschen jedes Element aus, das nicht an der ersten Stelle ist, an die es gehen kann. Dann machen Sie dasselbe mit jedem Element, das wir vertauscht haben, bis das aktuelle Element dort ist, wo es hingehört.
Erhöhen Sie den relativen Offset des relevanten Elements in der Nachschlagetabelle mit jedem Schritt.
Beachten Sie, dass es nicht möglich ist, das gleiche Element zweimal zu vertauschen, daher ist dies eine lineare Zeit.
Das ist alles sehr verwirrend klingt, also hier ein Beispiel:
4 5 3 1 2 3 4 4 1 5 4 3 2 3
// counts:
1: 2, 2: 2, 3: 4, 4: 4, 5: 2
// the starting points (offsets) based on the counts:
1 at position 0
2 at position (offset of 1)+(count of 1) = 0+2 = 2
3 at position (offset of 2)+(count of 2) = 2+2 = 4
4 at position (offset of 3)+(count of 3) = 4+4 = 8
5 at position (offset of 4)+(count of 4) = 8+4 = 12
// sorting:
4 5 3 1 2 3 4 4 1 5 4 3 2 3 // out of place, swap with offsets[4] = 8 (offsets[4]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // in correct position, moving on (offsets[1]++)
^
1 5 3 1 2 3 4 4 4 5 4 3 2 3 // swap with offsets[5] = 12 (offsets[5]++)
^
1 2 3 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 2 (offsets[2]++)
^
1 3 2 1 2 3 4 4 4 5 4 3 5 3 // swap with offsets[3] = 4 (offsets[3]++)
^
1 2 2 1 3 3 4 4 4 5 4 3 5 3 // swap with offsets[2] = 3 (offsets[2]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[1]++)
^
1 1 2 2 3 3 4 4 4 5 4 3 5 3 // in correct position, moving on (offsets[2]++)
^
Sie erhalten die Idee ...
Beachten Sie, dass die Größe der Zählertabelle und die Lookup-Tabelle O(max value)
sind , die O(1)
ist, wenn jede Nummer eine feste Anzahl von Bits enthält.
Und Sie tun eine konstante Menge an Arbeit für jedes Element, so dass O(n)
Zeit ist.
Die In-Place MSD Radix Sortierung ist, was ich gesucht habe, danke! – Konrad
@Konrad Ich fügte meiner Antwort eine andere Lösung hinzu, basierend auf dem Zählen der Sortierung. – Dukeling