Radix-Sort für Negative Ganzzahlen
Bin ich versucht zu implementieren radix-sort für Ganzzahlen einschließlich negative zahlen. Für nicht-negative int-Werte, die ich planen, zu erstellen Sie eine Warteschlange von 10 queues entsprechend für die Ziffern 0-9 und die Umsetzung der LSD-Algorithmus. Aber ich war irgendwie verwirrt mit den negativen ganzen zahlen. Was ich jetzt denke, ist, gehen Sie voran und erstellen Sie eine andere Warteschlange von 10 queues für Sie und separat sortiert und dann, am Ende, ich gab 2 Listen, eine mit negativen int-Werten sortiert und die anderen, die nicht-negative Ganzzahlen. Und schließlich würde ich Sie Zusammenführen.
Was haltet Ihr von diesem? Ist es effizienter Umgang mit negativen ganzen zahlen?
Danke!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie behandeln das Zeichen als eine Besondere Art von Stelle. Sie Sortieren die Stapel auf die Einheiten, dann die Zehner, etc. und schließlich auf dem Schild. Dies erzeugt eine umgekehrte Reihenfolge für die negative, du dann einfach rückwärts den Inhalt der Eimer. Es ist so alt wie die mechanische Karten-Sortierer gearbeitet.
Beachten Sie, dass das Vorzeichen-bit wird das oberste bit in einer signed integer, aber alle zahlen behandelt werden, die von radix-sort als unsigned Integer standardmäßig. Sie müssen also sagen, der Algorithmus, der die negativen zahlen sind kleiner als die positiven. Im Fall von 32-bit-Ganzzahlen mit Vorzeichen, können Sie eine Sortierreihenfolge für drei unteren Byte zuerst, dann Sortieren Sie die vierte (Obere) byte mit dem Vorzeichen-bit invertiert, so dass 0 wird für negative zahlen verwendet anstelle von 1, und folglich werden Sie als erste gehen.
Empfehle ich dringend zum Sortieren von zahlen (byte-by-byte anstelle von Dezimalstellen, denn es ist viel leichter für die Maschine zu Holen bytes als Auszug stellen.
Eine weitere Lösung ist die Trennung von negativen ganzen zahlen von der Reihe, machen Sie positive, Art als positive Werte mit radix, dann drehen Sie es und fügen Sie mit sortierten nicht-negative array.
Absolut! Man muss natürlich aufpassen, dass Sie von der Aufteilung des negativen vom positiven, aber zum Glück ist dies ganz einfach. Am Anfang des Algorithmus Sortieren alles, was Sie tun müssen, ist Ihre partition-array um den Wert 0. Danach radix-Sortierung unter-und oberhalb der Trennwand.
Hier ist der Algorithmus in der Praxis. Ich abgeleitet, das von Kevin Wayne und Bob Sedgewick ist MSD-radix-sort: http://algs4.cs.princeton.edu/51radix/MSD.java.html
Wohl die einfachste Art das zu handhaben, signierte Werte für den Versatz der Startposition für die Akkumulation (d.h., die Generierung von positions-offsets) bei Betrieb an den meisten signifikante Ziffer. Die Umwandlung der Eingabe, so werden alle Ziffern behandelt werden dürfen als unsigned ist auch eine option, erfordert aber die Anwendung eines Vorgangs über die array Werte mindestens zweimal (einmal, um vorzubereiten, die Eingang und um wieder die Ausgabe).
Diese nutzt die erste Technik sowie byte-Größe stellen (byte-Zugriff ist in der Regel effizienter):
Hinweis: Code ist ungetestet. Entschuldigungen für Fehler/Tippfehler.
Ihrem radix-sort nicht schneller sein als der berühmte Vergleich von Sorten, wenn Sie nicht verwenden "bitshift" und "bitweise UND" für radix Berechnung.
Computer verwenden 2 ergänzen zu vertreten, unterzeichnet zahlen, hier das sign-bit liegt am äußersten linken Ende eine binäre Ziffer, die in dem Hauptspeicher
eg
436163157 (als 32 bit-Zahl) = 00011001 11111111 01010010 01010101
-436163157 (als 32 bit-Zahl) = 11100110 00000000 10101101 10101011
1 (als 32 bit-Zahl) = 00000000 00000000 00000000 00000001
-1 (als 32 bit-Zahl) = 11111111 1111111 1111111 11111111
0 wird dargestellt als = 00000000 00000000 00000000 00000000
Höchsten negativen Wert as = 10000000 00000000 00000000 00000000
Damit Sie sehen, desto mehr negative einer Zahl wird, verliert es, dass viele 1, eine kleine negative Zahl hat viele 1, wenn Sie nur das Vorzeichen-bit 0 ist, wird es eine sehr große positive Zahl ist. Umgekehrt ist eine kleine positive Zahl ist, wird eine große negative Zahl.
Im radix sort die Schlüssel zu Sortieren negativen zahlen ist, wie Sie behandeln die letzten 8 bit für negative zahlen mindestens das Letzte bit muss 1 sein, in 32-bit-System, es hat aus
10000000 00000000 00000000 00000000 die die meisten negativen Wert, der am weitesten von null auf 11111111 11111111 11111111 11111111, das ist -1. Wenn man sich die linken 8 bits, die Größenordnung reicht von 10000000 bis 11111111, also von 128 bis 255.
Diese Werte können erhalten werden, indem dieser code Stück
Für negative zahlen V wird immer die Lüge von 128 bis 255. Für positive zahlen, es wird von 0 bis 127. Wie bereits gesagt, der Wert von M wird 255 -1 und 128 für höchste negative Zahl in 32-bit-System. Bauen Sie sich Ihr Histogramm als üblich. Dann ab index 128 bis 255 zu tun, die kumulative Summe, dann fügen Sie die Frequenz von 255 auf 0 aus, und fahren Sie die kumulative Summe von 0 bis index 127. Führen Sie die Art, wie üblich. Diese Technik ist sowohl eine optimale, schnelle, elegante und gepflegte sowohl in der Theorie und in der Praxis. Keine Notwendigkeit, jede Art von separaten Listen noch, um die Umkehr nach der Sortierung noch die Konvertierung aller Eingänge zu positiven, welche die Art langsam und chaotisch.
Für den code sehen Radix-Sort Optimierung
64-bit-version gebaut werden kann, mit der gleichen Konzepte
Weiter Lesen:
http://codercorner.com/RadixSortRevisited.htm
http://stereopsis.com/radix.html
Diese kann getan werden, ohne Partitionierung oder dass praktisch invertieren des MSB. Hier ist eine funktionierende Lösung in Java:
Akzeptiert die Antwort erfordert einen pass mehr als notwendig.
Spiegeln nur das Vorzeichen-bit.
Dies ist im wesentlichen die Antwort gepostet von punpcklbw, aber es gibt eine kleine Einschränkung, die behandelt werden muss. Konkret wird angenommen, Sie arbeiten mit einem zweier-Komplement-Darstellung, die wahr ist für 99,999% der uns. Zum Beispiel, Java und Rost festlegen, dass signierte ganze zahlen verwenden zweier-Komplement. Die C-und C++ - Spezifikationen erfordern keine spezifischen format, aber weder MSVC, GCC, noch LLVM support sonstigen Darstellungen. In der Montage, In fast jedem CPU-beschäftigen Sie sich mit zweier-Komplement, und Sie werden sicherlich schon wissen, sonst.
Die folgende Tabelle zeigt, dass die spiegelung einfach das Vorzeichen-bit wird dazu führen, dass zwei-Komplement-Ganzzahlen zu Sortieren richtig, wenn Sie lexikographisch sortiert. Die erste Spalte gibt einen binary-Wert, die zweite Spalte gibt die interpretation der bits als 4-bit-Ganzzahlen mit Vorzeichen, und die Dritte Spalte gibt die interpretation der bits mit dem hohen bit umgedreht.
Die Antwort punpcklbw empfiehlt spiegeln nur das bit, wenn Sie das höchste byte, aber mein Bauchgefühl sagt mir, es wäre schneller, einfach flip das oberste bit jedes mal, bevor Sie ziehen Sie das byte, die Sie suchen. Das ist, weil dabei ein einziges xor-jeder Zeit spiegeln, die etwas schneller sein wird als ein Zweig jedes mal zu entscheiden, ob flip oder nicht.
[Ein wichtiges detail zu erwähnen, die einige Lehrbücher nicht richtig ist, dass eine wirkliche Umsetzung sollte die Sortierung nach byte, nicht durch die dezimale Ziffer. Dies ist natürlich immer noch korrekt, weil Sie nur die Sortierung durch eine Wurzel von 256 statt 10, aber denken Sie an es auf diese Weise führt zu einer besseren Implementierungen.]