{"id":31807,"date":"2022-07-19T11:01:28","date_gmt":"2022-07-19T09:01:28","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=31807"},"modified":"2025-06-12T09:25:09","modified_gmt":"2025-06-12T07:25:09","slug":"radix-sort","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/algorithmen\/radix-sort\/","title":{"rendered":"Radix Sort \u2013 Algorithmus, Quellcode, Zeitkomplexit\u00e4t"},"content":{"rendered":"\n<p>In diesem Artikel lernst du den Sortieralgorithmus \"Radix Sort\" kennen. Du erf\u00e4hrst:<\/p>\n\n\n\n<ul class=\"wp-block-list hc-checked-list\">\n<li><span style=\"color: initial;\">Wie funktioniert Radix Sort? (Schritt f\u00fcr Schritt)<\/span><\/li>\n\n\n\n<li>Wie implementiert man Radix Sort in Java?<\/li>\n\n\n\n<li>Welche Zeit- und Platzkomplexit\u00e4t hat Radix Sort?<\/li>\n\n\n\n<li>Welche Varianten gibt es von Radix Sort?<\/li>\n\n\n\n<li>... und was bedeutet \u00fcberhaupt der Begriff \"Radix\"?<\/li>\n<\/ul>\n\n\n\n<p>Fangen wir mit der letzten Frage an:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"was-ist-radix-sort\">Was ist Radix Sort?<\/h2>\n\n\n\n<p>\"Radix\" ist zwar das lateinische Wort f\u00fcr \"Wurzel\" \u2013 dennoch hat Radix Sort nichts mit Wurzelziehen zu tun.<\/p>\n\n\n\n<p>Die \"Radix\" eines Zahlensystems (auch \"Basis\" genannt) bezeichnet vielmehr die Anzahl der Ziffern, die zur Darstellung von Zahlen in diesem Zahlensystem ben\u00f6tigt werden. Die Radix im Dezimalsystem ist 10, die Radix des Bin\u00e4rsystems ist 2, und die Radix des Hexadezimalsystems ist 16.<\/p>\n\n\n\n<p>Bei Radix Sort sortieren wir die Zahlen <em>Ziffer f\u00fcr Ziffer<\/em> \u2013 und nicht, wie bei den meisten anderen Sortierverfahren, indem wir zwei <em>Zahlen<\/em> miteinander vergleichen. Wie genau das funktioniert, liest du im folgenden Kapitel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-algorithmus\">Radix Sort Algorithmus<\/h2>\n\n\n\n<p>Den Algorithmus f\u00fcr Radix Sort erkl\u00e4re ich am besten Schritt f\u00fcr Schritt an einem Beispiel. Folgende Zahlen sollen sortiert werden:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"39\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-600x39.png\" alt=\"Radix Sort Algorithmus - zu sortierende Zahlen\" class=\"wp-image-31857\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-600x39.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-224x15.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-336x22.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-504x33.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-672x44.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-400x26.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-800x52.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-944x61.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort-1180x78.png 1180w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-numbers-to-sort.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Wir betrachten zu Beginn ausschlie\u00dflich die <em>letzte<\/em> Ziffer (es gibt auch Radix-Sort-Varianten, bei denen man bei der <em>ersten<\/em> Ziffer beginnt, aber dazu kommen wir sp\u00e4ter):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"39\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-600x39.png\" alt=\"Radix Sort Algorithmus - letzte Ziffer markiert\" class=\"wp-image-31858\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-600x39.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-224x15.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-336x22.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-504x33.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-672x44.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-400x26.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-800x52.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-944x61.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted-1180x78.png 1180w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-highlighted.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Wir sortieren die Zahlen in zwei Phasen: einer Partitionierungsphase und einer Sammelphase.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"partitionierungsphase\">Partitionierungsphase<\/h3>\n\n\n\n<p>F\u00fcr die Partitionierung legen wir zehn sogenannte \"Buckets\" an, bezeichnet mit \"0\" bis \"9\". Auf diese verteilen wir die Zahlen entsprechend ihrer jeweils letzten Ziffer. Die folgende Grafik demonstriert, wie wir die erste Zahl, die 41, in den Bucket \"1\" legen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-600x416.png\" alt=\"Radix Sort - Partitionierungsphase - Schritt 1\" class=\"wp-image-31859\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step1.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die zweite Zahl, die 573, legen wir, entsprechend ihrer letzten Ziffer, in den Bucket \"3\":<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"417\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-600x417.png\" alt=\"Radix Sort - Partitionierungsphase - Schritt 2\" class=\"wp-image-31905\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-600x417.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-224x156.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-336x234.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-504x350.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-672x467.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-400x278.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-800x556.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2-944x656.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step2.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die dritte Zahl, die 3, legen wir ebenfalls in den Bucket \"3\":<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-600x416.png\" alt=\"Radix Sort - Partitionierungsphase - Schritt 3\" class=\"wp-image-31906\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step3.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Auf die gleiche Art verteilen wir auch die restlichen Zahlen auf die Buckets:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-600x416.png\" alt=\"Radix Sort - Partitionierungsphase - Schritte 4 bis 7\" class=\"wp-image-31907\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-partitioning-step4-7.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Partitionierungsphase f\u00fcr die letzte Ziffer ist damit abgeschlossen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"sammelphase\">Sammelphase<\/h3>\n\n\n\n<p>An die Partitionierungsphase schlie\u00dft sich die Sammelphase an. Wir sammeln die Zahlen, Bucket f\u00fcr Bucket, in aufsteigender Reihenfolge \u2013 und innerhalb der Buckets von links nach rechts (also in der gleichen Reihenfolge wie die Zahlen in den jeweiligen Bucket eingetragen wurden) \u2013 in eine neue Liste.<\/p>\n\n\n\n<p>Wir beginnen mit dem Buckets mit der kleinsten Ziffer, also Bucket 1:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-600x416.png\" alt=\"Radix Sort - Sammelphase - Bucket 1\" class=\"wp-image-31878\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-1.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Danach sammeln wir die Zahlen des n\u00e4chsth\u00f6heren Buckets, also Bucket 3:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-600x416.png\" alt=\"Radix Sort - Sammelphase - Bucket 3\" class=\"wp-image-31908\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-3.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Und schlie\u00dflich die Zahlen aus Bucket 6 und dann Bucket 8:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-600x416.png\" alt=\"Radix Sort - Sammelphase - Bucket 6 und 8\" class=\"wp-image-31909\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-bucket-6-8.v2.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Alle Buckets sind nun geleert:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-600x416.png\" alt=\"Radix Sort - Sammelphase abgeschlossen\" class=\"wp-image-31910\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-last-digit-collection-done.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>In dieser neuen Liste sind die Zahlen nach ihrer letzten Ziffer aufsteigend sortiert: 1, 1, 3, 3, 3, 6, 8<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"nach-zehnerstelle-sortieren\">Nach Zehnerstelle sortieren<\/h3>\n\n\n\n<p>Wir wiederholen die Partitionierungs- und Sammelphase f\u00fcr die Zehnerstelle. Die zwei Phasen stelle ich dieses Mal mit nur jeweils einer Grafik dar.<\/p>\n\n\n\n<p>In der Partitionierungsphase verteilen wir die Zahlen nach ihrer Zehnerstelle auf die Buckets:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"417\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-600x417.png\" alt=\"Radix Sort - Partitionierung nach Zehnerstelle\" class=\"wp-image-31874\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-600x417.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-224x156.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-336x234.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-504x350.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-672x467.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-400x278.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-800x556.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning-944x656.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-partitioning.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Zehnerstelle von <em>einstelligen<\/em> Zahlen ist die Null. Dementsprechend habe ich die Drei als \"03\" dargestellt.<\/p>\n\n\n\n<p>In der Sammelphase entnehmen wir die Zahlen wieder Bucket f\u00fcr Bucket:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-600x416.png\" alt=\"Radix Sort - Sammlung der Zehner-Buckets\" class=\"wp-image-31876\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-middle-digit-collection.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Zahlen sind nun nach ihren jeweils <em>zwei<\/em> letzten Ziffern sortiert: 3, 8, 36, 41, 71, 73, 93<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"nach-hunderterstelle-sortieren\">Nach Hunderterstelle sortieren<\/h3>\n\n\n\n<p>Die gleiche Prozedur wiederholen wir f\u00fcr die Hunderterstelle. Zun\u00e4chst die Partitionierungsphase:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"424\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-600x424.png\" alt=\"Radix Sort - Partitionierung nach Hunderterstelle\" class=\"wp-image-31898\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-600x424.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-224x158.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-336x237.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-504x356.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-672x475.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-400x283.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-800x565.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning-944x667.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-partitioning.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Und im Anschluss die Sammelphase:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"416\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-600x416.png\" alt=\"Radix Sort - Sammlung der Hunderter-Buckets\" class=\"wp-image-31899\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-600x416.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-224x155.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-336x233.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-504x349.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-672x466.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-400x277.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-800x555.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection-944x655.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-first-digit-collection.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Nach der dritten und letzten Sammelphase sind die Zahlen nun vollst\u00e4ndig sortiert.<\/p>\n\n\n\n<p>Hier noch einmal das Endergebnis ohne f\u00fchrende Nullen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"38\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-600x38.png\" alt=\"Radix Sort Algorithmus - Endergebnis\" class=\"wp-image-31900\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-600x38.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-224x14.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-336x21.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-504x32.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-672x43.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-400x25.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-800x51.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-944x60.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted-1180x76.png 1180w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-all-numbers-sorted.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Im n\u00e4chsten Kapitel kommen wir zur Implementierung von Radix Sort.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-in-java\">Radix Sort in Java<\/h2>\n\n\n\n<p>Radix Sort kann auf verschiedene Weisen implementiert werden. Wir beginnen mit einer einfachen Variante, die sich sehr nah am beschriebenen Algorithmus orientiert. Danach zeige ich dir zwei alternative Implementierungen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"variante-1-radix-sort-mit-dynamischen-listen\">Variante 1: Radix Sort mit dynamischen Listen<\/h3>\n\n\n\n<p>Wir fangen mit einer leeren <code>sort()<\/code>-Methode an und f\u00fcllen diese Schritt f\u00fcr Schritt.<\/p>\n\n\n\n<p>(Das Endergebnis findest du am Ende dieses Abschnitts und in der Klasse <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithDynamicLists.java\" target=\"_blank\">RadixSortWithDynamicLists<\/a> im GitHub-Repository dieser Sortier-Tutorial-Serie.)<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> class RadixSortWithDynamicLists\n\n  <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-comment\">\/\/ We will implement this method step by step...<\/span>\n  }\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Da wir die zwei Phasen (Partitionierungsphase und Sammelphase) f\u00fcr jede Ziffer wiederholen m\u00fcssen, m\u00fcssen wir zun\u00e4chst einmal feststellen, wie viele Ziffern unsere Zahlen \u00fcberhaupt haben.<\/p>\n\n\n\n<p>Das tun wir, indem wir die gr\u00f6\u00dfte Zahl aus dem zu sortierenden Array ermitteln und danach z\u00e4hlen, wie oft sich diese Zahl durch 10 teilen l\u00e4sst:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> class RadixSortWithDynamicLists\n\n  <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n    <span class=\"hljs-comment\">\/\/ <span class=\"hljs-doctag\">TODO:<\/span> Implement the partitioning and collection phases<\/span>\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getMaximum<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> max = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n      <span class=\"hljs-keyword\">if<\/span> (element &gt; max) {\n        max = element;\n      }\n    }\n    <span class=\"hljs-keyword\">return<\/span> max;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getNumberOfDigits<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> number)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">while<\/span> (number &gt;= <span class=\"hljs-number\">10<\/span>) {\n      number \/= <span class=\"hljs-number\">10<\/span>;\n      numberOfDigits++;\n    }\n    <span class=\"hljs-keyword\">return<\/span> numberOfDigits;\n  }\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Danach sortieren wir Ziffer f\u00fcr Ziffer. Dazu schreiben wir eine <code>for<\/code>-Schleife mit der Schleifenvariable <code>digitIndex<\/code>, wobei 0 f\u00fcr die Einerstelle steht, 1 f\u00fcr die Zehnerstelle, 2 f\u00fcr die Hunderterstelle, usw.<\/p>\n\n\n\n<p>(In den folgenden Listings drucke ich die Klasse selbst nicht mehr mit ab, nur noch die Methoden <em>innerhalb<\/em> der Klasse.)<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n  <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> digitIndex = <span class=\"hljs-number\">0<\/span>; digitIndex &lt; numberOfDigits; digitIndex++) {\n    <span class=\"hljs-comment\">\/\/ <span class=\"hljs-doctag\">TODO:<\/span> Sort elements by digit at 'digitIndex'<\/span>\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>F\u00fcr den n\u00e4chsten Schritt ben\u00f6tigen wir die Buckets, auf die wir die Zahlen verteilen k\u00f6nnen. Wir k\u00f6nnten hierf\u00fcr zehn <code>ArrayList<\/code>s verwenden.<\/p>\n\n\n\n<p>Eleganter ist es jedoch diese in eine <code>Bucket<\/code>-Klasse zu wrappen. Das macht zum einen den Code lesbarer; zum anderen erm\u00f6glicht es uns sp\u00e4ter die Implementierung der Buckets zu \u00e4ndern, ohne den restlichen Code anpassen zu m\u00fcssen.<\/p>\n\n\n\n<p>Die <code>Bucket<\/code>-Klasse k\u00f6nnen wir als innere Klasse innerhalb der Klasse <code>RadixSortWithDynamicLists<\/code> anlegen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Bucket<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> List&lt;Integer&gt; elements = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">add<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> element)<\/span> <\/span>{\n    elements.add(element);\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> List&lt;Integer&gt; <span class=\"hljs-title\">getElements<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> elements;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Das war die Vorbereitung.<\/p>\n\n\n\n<p>Kommen wir zur Partitionierungsphase. Wir ben\u00f6tigen zehn Buckets, auf die wir die Zahlen verteilen k\u00f6nnen; diese generieren wir mit einer <code>createBuckets()<\/code>-Methode:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> Bucket&#091;] createBuckets() {\n  Bucket&#091;] buckets = <span class=\"hljs-keyword\">new<\/span> Bucket&#091;<span class=\"hljs-number\">10<\/span>];\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n    buckets&#091;i] = <span class=\"hljs-keyword\">new<\/span> Bucket();\n  }\n  <span class=\"hljs-keyword\">return<\/span> buckets;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Danach verteilen wir unsere Zahlen anhand der aktuell betrachteten Stelle <code>digitIndex<\/code> auf die Buckets:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">distributeToBuckets<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex, Bucket&#091;] buckets)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n    <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n    buckets&#091;digit].add(element);\n  }\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">calculateDivisor<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> divisor = <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; digitIndex; i++) {\n    divisor *= <span class=\"hljs-number\">10<\/span>;\n  }\n  <span class=\"hljs-keyword\">return<\/span> divisor;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Der <code>divisor<\/code> ist dabei diejenige Zahl, durch die wir ein Element teilen m\u00fcssen, so dass an der hintersten Stelle die aktuell zu betrachtende Ziffer steht \u2013 also 1 f\u00fcr die Einerstelle, 10 f\u00fcr die Zehnerstelle, 100 f\u00fcr die Hunderterstelle, usw.<\/p>\n\n\n\n<p>Die Methoden der Partitionierungsphase fassen wir in einer <code>partition()<\/code>-Methode zusammen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> Bucket&#091;] partition(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n  Bucket&#091;] buckets = createBuckets();\n  distributeToBuckets(elements, digitIndex, buckets);\n  <span class=\"hljs-keyword\">return<\/span> buckets;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In der Sammelphase m\u00fcssen wir nun lediglich die Zahlen der einzelnen Buckets aneinanderreihen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">collect<\/span><span class=\"hljs-params\">(Bucket&#091;] buckets, <span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> targetIndex = <span class=\"hljs-number\">0<\/span>;\n  <span class=\"hljs-keyword\">for<\/span> (Bucket bucket : buckets) {\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : bucket.getElements()) {\n      elements&#091;targetIndex] = element;\n      targetIndex++;\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>partition()<\/code>- und <code>collect()<\/code>-Methoden fassen wir in einer <code>sortByDigit()<\/code>-Methode zusammen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sortByDigit<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n  Bucket&#091;] buckets = partition(elements, digitIndex);\n  collect(buckets, elements);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und jetzt schlie\u00dfen wir den Kreis, indem wir die <code>sortByDigit()<\/code>-Methode aus der <code>digitIndex<\/code>-Schleife der zu Beginn gezeigten <code>sort()<\/code>-Methode heraus aufrufen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n  <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> digitIndex = <span class=\"hljs-number\">0<\/span>; digitIndex &lt; numberOfDigits; digitIndex++) {\n    sortByDigit(elements, digitIndex);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Damit ist unserer Radix-Sort-Implementierung abgeschlossen.<\/p>\n\n\n\n<p>Hier siehst du noch einmal den vollst\u00e4ndigen Quellcode:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RadixSortWithDynamicLists<\/span> <\/span>{\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> digitIndex = <span class=\"hljs-number\">0<\/span>; digitIndex &lt; numberOfDigits; digitIndex++) {\n      sortByDigit(elements, digitIndex);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getMaximum<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> max = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n      <span class=\"hljs-keyword\">if<\/span> (element &gt; max) {\n        max = element;\n      }\n    }\n    <span class=\"hljs-keyword\">return<\/span> max;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getNumberOfDigits<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> number)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">while<\/span> (number &gt;= <span class=\"hljs-number\">10<\/span>) {\n      number \/= <span class=\"hljs-number\">10<\/span>;\n      numberOfDigits++;\n    }\n    <span class=\"hljs-keyword\">return<\/span> numberOfDigits;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sortByDigit<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n    Bucket&#091;] buckets = partition(elements, digitIndex);\n    collect(buckets, elements);\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> Bucket&#091;] partition(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n    Bucket&#091;] buckets = createBuckets();\n    distributeToBuckets(elements, digitIndex, buckets);\n    <span class=\"hljs-keyword\">return<\/span> buckets;\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> Bucket&#091;] createBuckets() {\n    Bucket&#091;] buckets = <span class=\"hljs-keyword\">new<\/span> Bucket&#091;<span class=\"hljs-number\">10<\/span>];\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n      buckets&#091;i] = <span class=\"hljs-keyword\">new<\/span> Bucket();\n    }\n    <span class=\"hljs-keyword\">return<\/span> buckets;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">distributeToBuckets<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex, Bucket&#091;] buckets)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n      <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n      buckets&#091;digit].add(element);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">calculateDivisor<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> divisor = <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; digitIndex; i++) {\n      divisor *= <span class=\"hljs-number\">10<\/span>;\n    }\n    <span class=\"hljs-keyword\">return<\/span> divisor;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">collect<\/span><span class=\"hljs-params\">(Bucket&#091;] buckets, <span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> targetIndex = <span class=\"hljs-number\">0<\/span>;\n    <span class=\"hljs-keyword\">for<\/span> (Bucket bucket : buckets) {\n      <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : bucket.getElements()) {\n        elements&#091;targetIndex] = element;\n        targetIndex++;\n      }\n    }\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Bucket<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> List&lt;Integer&gt; elements = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">add<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> element)<\/span> <\/span>{\n      elements.add(element);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> List&lt;Integer&gt; <span class=\"hljs-title\">getElements<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n      <span class=\"hljs-keyword\">return<\/span> elements;\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithDynamicLists.java\" target=\"_blank\">RadixSortWithDynamicLists<\/a>-Klasse im GitHub-Repository unterscheidet sich \u00fcbrigens leicht von dem hier abgedruckten Quellcode:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sie implementiert das Interface <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/SortAlgorithm.java\" target=\"_blank\" rel=\"noopener\">SortAlgorithm<\/a>, das es erm\u00f6glicht verschiedene Radix-Sort-Implementierungen miteinander und mit den anderen Algorithmen der Sortieralgorithmen-Serie zu vergleichen.<\/li>\n\n\n\n<li>Die <code>getMaximum()<\/code>-Methode ist in die Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/utils\/ArrayUtils.java\" target=\"_blank\" rel=\"noopener\">ArrayUtils<\/a> ausgelagert.<\/li>\n\n\n\n<li>Die Methoden <code>getNumberOfDigits()<\/code> und <code>calculateDivisor()<\/code> liegen in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortHelper.java\" target=\"_blank\" rel=\"noopener\">RadixSortHelper<\/a> und k\u00f6nnen so auch in anderen Radix-Sort-Implementierungen verwendet werden.<\/li>\n<\/ul>\n\n\n\n<p>Die gezeigte Implementierung hat ein Manko: <\/p>\n\n\n\n<p>Dynamische Listen (also Listen, deren Gr\u00f6\u00dfe sich zur Laufzeit \u00e4ndern kann) sind f\u00fcr leistungskritische Einsatzzwecke wie Sortieralgorithmen nicht optimal, da das Hinzuf\u00fcgen von Elementen mit einem gewissen Performance-Overhead verbunden ist (bei einer verketteten Liste beispielsweise m\u00fcssen neue Knoten angelegt werden; bei einer <code>ArrayList<\/code> muss das Array in bestimmten Abst\u00e4nden in ein gr\u00f6\u00dferes umkopiert werden).<\/p>\n\n\n\n<p>Im n\u00e4chsten Abschnitt zeige ich dir daher eine alternativen Variante.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"variante-2-radix-sort-mit-arrays\">Variante 2: Radix Sort mit Arrays<\/h3>\n\n\n\n<p>Wir k\u00f6nnen die Implementierung deutlich beschleunigen (wir werden die Performance der Implementierungen im Anschluss vergleichen), indem wir f\u00fcr die Buckets statt einer <code>ArrayList<\/code> ein Array verwenden.<\/p>\n\n\n\n<p>Da Arrays eine feste Gr\u00f6\u00dfe haben, m\u00fcssen wir vor der Erstellung eines Buckets wissen, wie viele Elemente der Bucket enthalten soll. Wir \u00e4ndern unsere <code>Bucket<\/code>-Klasse wie folgt ab und \u00fcbergeben die Gr\u00f6\u00dfe an dessen Konstruktor:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Bucket<\/span> <\/span>{\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] elements;\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> addIndex;\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-title\">Bucket<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> size)<\/span> <\/span>{\n    elements = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;size];\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">add<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> element)<\/span> <\/span>{\n    elements&#091;addIndex] = element;\n    addIndex++;\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] getElements() {\n    <span class=\"hljs-keyword\">return<\/span> elements;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Um zu bestimmen, wie viele Elemente ein Bucket enthalten soll, z\u00e4hlen wir vorab die Ziffern an der aktuell betrachteten Stelle <code>digitIndex<\/code>. Die <code>partition()<\/code>-Methode sieht dann so aus:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">private<\/span> Bucket&#091;] partition(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n  <span class=\"hljs-keyword\">int<\/span>&#091;] counts = countDigits(elements, digitIndex);\n  Bucket&#091;] buckets = createBuckets(counts);\n  distributeToBuckets(elements, digitIndex, buckets);\n  <span class=\"hljs-keyword\">return<\/span> buckets;\n}\n\n<span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] countDigits(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n  <span class=\"hljs-keyword\">int<\/span>&#091;] counts = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;<span class=\"hljs-number\">10<\/span>];\n  <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n    <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n    counts&#091;digit]++;\n  }\n  <span class=\"hljs-keyword\">return<\/span> counts;\n}\n\n<span class=\"hljs-keyword\">private<\/span> Bucket&#091;] createBuckets(<span class=\"hljs-keyword\">int<\/span>&#091;] counts) {\n  Bucket&#091;] buckets = <span class=\"hljs-keyword\">new<\/span> Bucket&#091;<span class=\"hljs-number\">10<\/span>];\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n    buckets&#091;i] = <span class=\"hljs-keyword\">new<\/span> Bucket(counts&#091;i]);\n  }\n  <span class=\"hljs-keyword\">return<\/span> buckets;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die <code>distributeToBuckets()<\/code>-Methode brauchen wir nicht zu \u00e4ndern, ebensowenig alle anderen in Variante 1 gezeigten Methoden. Gut, dass wir in Variante 1 eine <code>Bucket<\/code>-Klasse verwendet haben und nicht direkt eine <code>ArrayList<\/code> :-)<\/p>\n\n\n\n<p>Den vollst\u00e4ndigen Code von Variante 2 findest du im GitHub-Repository in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithArrays.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithArrays<\/a>.<\/p>\n\n\n\n<p>Kommen wir zu einer dritten Variante.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"variante-3-radix-sort-mit-counting-sort\">Variante 3: Radix Sort mit Counting Sort<\/h3>\n\n\n\n<p>In Variante 2 haben wir vorab gez\u00e4hlt, wie viele Elemente in jeden Bucket sortiert werden m\u00fcssen. Mit dieser Information k\u00f6nnen wir die Buckets auch \u00fcberspringen und die Elemente direkt an ihre Zielpositionen verschieben. Und zwar indem wir die <a href=\"\/de\/algorithmen\/counting-sort\/#Counting_Sort_Algorithmus_Allgemeine_Form\">allgemein Form von Counting Sort<\/a> anwenden.<\/p>\n\n\n\n<p>Wie Counting Sort funktioniert, werde ich an dieser Stelle nicht noch einmal wiederholen. Ich zeige dir direkt die Implementierung:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RadixSortWithCountingSort<\/span> <\/span>{\n\n  <span class=\"hljs-meta\">@Override<\/span>\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n    <span class=\"hljs-comment\">\/\/ Remember input array<\/span>\n    <span class=\"hljs-keyword\">int<\/span>&#091;] inputArray = elements;\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> digitIndex = <span class=\"hljs-number\">0<\/span>; digitIndex &lt; numberOfDigits; digitIndex++) {\n      elements = sortByDigit(elements, digitIndex);\n    }\n\n    <span class=\"hljs-comment\">\/\/ Copy sorted elements back to input array<\/span>\n    System.arraycopy(elements, <span class=\"hljs-number\">0<\/span>, inputArray, <span class=\"hljs-number\">0<\/span>, elements.length);\n  }\n\n  <span class=\"hljs-comment\">\/\/ Same as in the other variants:<\/span>\n  <span class=\"hljs-comment\">\/\/ getMaximum(), getNumberOfDigits(), calculateDivisor() <\/span>\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] sortByDigit(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n    <span class=\"hljs-keyword\">int<\/span>&#091;] counts = countDigits(elements, digitIndex);\n    <span class=\"hljs-keyword\">int<\/span>&#091;] prefixSums = calculatePrefixSums(counts);\n    <span class=\"hljs-keyword\">return<\/span> collectElements(elements, digitIndex, prefixSums);\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] countDigits(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex) {\n    <span class=\"hljs-keyword\">int<\/span>&#091;] counts = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;<span class=\"hljs-number\">10<\/span>];\n    <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n      <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n      counts&#091;digit]++;\n    }\n    <span class=\"hljs-keyword\">return<\/span> counts;\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] calculatePrefixSums(<span class=\"hljs-keyword\">int<\/span>&#091;] counts) {\n    <span class=\"hljs-keyword\">int<\/span>&#091;] prefixSums = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;<span class=\"hljs-number\">10<\/span>];\n    prefixSums&#091;<span class=\"hljs-number\">0<\/span>] = counts&#091;<span class=\"hljs-number\">0<\/span>];\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">1<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n      prefixSums&#091;i] = prefixSums&#091;i - <span class=\"hljs-number\">1<\/span>] + counts&#091;i];\n    }\n    <span class=\"hljs-keyword\">return<\/span> prefixSums;\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;] collectElements(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex, <span class=\"hljs-keyword\">int<\/span>&#091;] prefixSums) {\n    <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n    <span class=\"hljs-keyword\">int<\/span>&#091;] target = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-keyword\">int<\/span>&#091;elements.length];\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = elements.length - <span class=\"hljs-number\">1<\/span>; i &gt;= <span class=\"hljs-number\">0<\/span>; i--) {\n      <span class=\"hljs-keyword\">int<\/span> element = elements&#091;i];\n      <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n      target&#091;--prefixSums&#091;digit]] = element;\n    }\n    <span class=\"hljs-keyword\">return<\/span> target;\n  }\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Diesen Code findest du ebenfalls im GitHub-Repository, in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithCountingSort.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithCountingSort<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-varianten\">Radix Sort Varianten<\/h2>\n\n\n\n<p>Es gibt zwei grundlegende Varianten von Radix Sort, die sich durch die Reihenfolge unterscheiden, in der wir die Ziffern der Elemente betrachten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"lsd-radix-sort\">LSD Radix Sort<\/h3>\n\n\n\n<p>Der im ersten Kapitel gezeigte Radix-Sort-Algorithmus nennt sich \"LSD Radix Sort\". LSD steht dabei f\u00fcr \"least significant digit\", also \"niedrigstwertige Stelle\". Wir haben mit dem Sortieren bei der niedrigstwertigen Stelle (den Einern) begonnen und uns Ziffer f\u00fcr Ziffer bis zur h\u00f6chstwertigen Stelle vorgearbeitet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"msd-radix-sort\">MSD Radix Sort<\/h3>\n\n\n\n<p>Alternativ k\u00f6nnen wir auch bei der h\u00f6chstwertigen Stelle, \"most significant digit\" beginnen. Entsprechend hei\u00dft die zweite Variante \"MSD Radix Sort\".<\/p>\n\n\n\n<p>Dabei m\u00fcssen wir allerdings anders vorgehen als bei der LSD-Variante. Denn wenn wir in unserem Ausgangsbeispiel die gesamte Eingabeliste zun\u00e4chst nach Hundertern, dann nach Zehnern und zuletzt nach der Einerstelle sortieren w\u00fcrden, w\u00fcrde folgendes passieren (die Buckets habe ich in der Grafik weggelassen, da es nur um die Ergebnisse nach den drei Collect-Phasen geht):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-half_600\"><img decoding=\"async\" width=\"600\" height=\"492\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-600x492.png\" alt=\"MSD Radix Sort - Wie es nicht funktioniert\" class=\"wp-image-31979\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-600x492.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-224x184.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-336x276.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-504x413.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-672x551.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-400x328.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-800x656.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way-944x774.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-wrong-way.png 1200w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Sortierung nach der Zehner- und Einerstelle hat die jeweiligen vorherigen Sortierungen wieder durcheinander gebracht.<\/p>\n\n\n\n<p>Das Problem ist schnell gel\u00f6st:<\/p>\n\n\n\n<p>Nach der Hunderterstelle d\u00fcrfen wir die Eingabeliste nicht erneut als Ganzes sortieren, sondern die Hunderterstellen-Buckets in sich. Die daraus wiederum resultierenden Zehnerstellen-Buckets sortieren wir dann jeweils nach der Einerstelle. Wir sortieren die Buckets also rekursiv.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"msd-radix-sort-schritt-fuer-schritt\">MSD Radix Sort \u2013 Schritt f\u00fcr Schritt<\/h3>\n\n\n\n<p>Die folgenden Grafiken zeigen das rekursive MSD-Radix-Sort-Verfahren Schritt f\u00fcr Schritt am Eingangsbeispiel. Buckets werden durch schwarze Klammern unter den Elementen dargestellt. Leere Buckets werden nicht angezeigt.<\/p>\n\n\n\n<p>Wir beginnen mit der Partitionierung nach Hunderterstellen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"197\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-800x197.png\" alt=\"MSD Radix Sort - Partitionierung nach Hunderterstelle\" class=\"wp-image-31985\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-800x197.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-224x55.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-336x83.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-504x124.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-672x165.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-400x99.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-600x148.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-944x232.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds-1200x296.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-hundreds.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Anstatt nun von der Partitionierungs- in die Sammelphase \u00fcberzugehen, f\u00fchren wir auf jedem Bucket eine weitere Partitionierungsphase aus \u2013 und zwar auf der n\u00e4chst niedrigeren Stelle, also den Zehnern.<\/p>\n\n\n\n<p>Leere Buckets und solche, die nur ein Element enthalten (wie die 271 und die 836), brauchen brauchen wir nicht weiter zu partitionieren.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"213\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-800x213.png\" alt=\"MSD Radix Sort - Partitionierung nach Zehnerstelle\" class=\"wp-image-31986\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-800x213.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-224x60.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-336x89.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-504x134.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-672x179.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-400x107.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-600x160.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-944x251.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens-1200x320.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-partition-tens.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Eigentlich m\u00fcssten wir die Buckets nun noch nach Einerstellen partitionieren. Da aber keiner der Zehnerstellen-Buckets mehr als ein Element enth\u00e4lt, ist das nicht notwendig.<\/p>\n\n\n\n<p>Wir steigen daher aus der Rekursion wieder aus. Zun\u00e4chst f\u00fchren wir eine Sammelphase auf den Zehnerstellen-Buckets aus:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"213\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-800x213.png\" alt=\"MSD Radix Sort - Sammlung der Zehner-Buckets\" class=\"wp-image-31988\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-800x213.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-224x60.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-336x89.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-504x134.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-672x179.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-400x107.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-600x160.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-944x251.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens-1200x320.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-tens.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Und zuletzt f\u00fchren wir die Sammelphase auf den Hunderterstellen-Buckets aus:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"197\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-800x197.png\" alt=\"MSD Radix Sort - Sammlung der Hunderter-Buckets\" class=\"wp-image-31989\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-800x197.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-224x55.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-336x83.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-504x124.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-672x165.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-400x99.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-600x148.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-944x232.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds-1200x296.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/msd-radix-sort-recursive-collect-hundreds.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Sortierung ist damit abgeschlossen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"msd-radix-sort-implementierung\">MSD Radix Sort \u2013 Implementierung<\/h3>\n\n\n\n<p>Genau wie die LSD-Variante kann auch MSD Radix Sort mit Dynamischen Listen, Arrays und mit Counting Sort implementiert werden.<\/p>\n\n\n\n<p>Ich zeige dir, wie du die oben gezeigte LSD-Array-Implementierung mit wenigen \u00c4nderungen in eine MSD-Implementierung \u00e4ndern kannst.<\/p>\n\n\n\n<p>Hier sind noch einmal die Methoden <code>sort()<\/code> und <code>sortByDigit()<\/code> der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithArrays.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithArrays<\/a>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n  <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> digitIndex = <span class=\"hljs-number\">0<\/span>; digitIndex &lt; numberOfDigits; digitIndex++) {\n    sortByDigit(elements, digitIndex);\n  }\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sortByDigit<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n  Bucket&#091;] buckets = partition(elements, digitIndex);\n  collect(buckets, elements);\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Alles was wir nun tun m\u00fcssen, ist die <code>sortByDigit()<\/code>-Methode f\u00fcr die h\u00f6chstwertige Stelle aufzurufen und zwischen Partitionierungs- und Sammelphase den rekursiven Aufruf f\u00fcr die n\u00e4chstniedrigere Stelle einzuf\u00fcgen:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sort<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> max = getMaximum(elements);\n  <span class=\"hljs-keyword\">int<\/span> numberOfDigits = getNumberOfDigits(max);\n\n  sortByDigit(elements, numberOfDigits - <span class=\"hljs-number\">1<\/span>);\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">sortByDigit<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n  Bucket&#091;] buckets = partition(elements, digitIndex);\n\n  <span class=\"hljs-comment\">\/\/ If we haven't reached the last digit, <\/span>\n  <span class=\"hljs-comment\">\/\/ sort the buckets by the next digit, recursively<\/span>\n  <span class=\"hljs-keyword\">if<\/span> (digitIndex &gt; <span class=\"hljs-number\">0<\/span>) {\n    <span class=\"hljs-keyword\">for<\/span> (Bucket bucket : buckets) {\n      <span class=\"hljs-keyword\">if<\/span> (bucket.needsToBeSorted()) {\n        sortByDigit(bucket.getElements(), digitIndex - <span class=\"hljs-number\">1<\/span>);\n      }\n    }\n  }\n\n  collect(buckets, elements);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Die Methode <code>Bucket.needsToBeSorted()<\/code> gibt <code>true<\/code> zur\u00fcck, wenn der Bucket wenigstens ein Element enth\u00e4lt.<\/p>\n\n\n\n<p>Den vollst\u00e4ndigen Code findest du im GitHub-Repository in der Klasse <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RecursiveMsdRadixSortWithArrays.java\" target=\"_blank\">RecursiveMsdRadixSortWithArrays<\/a>.<\/p>\n\n\n\n<p>Ich \u00fcberlasse es dir als \u00dcbungsaufgabe auch f\u00fcr die zwei anderen LSD-Implementierungen (dynamische Listen und Counting Sort) je eine MSD-Variante zu schreiben.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"verwendung-anderer-basen\">Verwendung anderer Basen<\/h3>\n\n\n\n<p>Bisher haben wir die Partitionierung nach dem Dezimalsystem, also mit 10 Buckets, durchgef\u00fchrt. Wir k\u00f6nnen aber auch mit jeder anderen Basis arbeiten, also beispielsweise mit dem Bin\u00e4rsystem (2 Buckets), dem Hexadezimalsystem (16 Buckets) oder auch mit hundert, tausend oder mehr Buckets.<\/p>\n\n\n\n<p>Je h\u00f6her die Basis, desto mehr Buckets, desto aufw\u00e4ndiger die Partitionierungsphase. Andererseits haben die zu sortierenden Zahlen dann weniger Stellen (1.000.000 dezimal = F4240 hexadezimal), so dass insgesamt weniger Partitionierungs- und Sammelphasen stattfinden m\u00fcssen. Was das f\u00fcr die Performance bedeutet, werden wir im Kapitel \"<a href=\"#radix-sort-laufzeit\">Radix Sort Laufzeit<\/a>\" ermitteln.<\/p>\n\n\n\n<p>Wie implementiert man Radix Sort mit einer anderen Basis?<\/p>\n\n\n\n<p>Im Grunde genommen m\u00fcssen wir jedes Vorkommen der Zahl 10 im Quellcode durch die neue Basis ersetzen. In der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithDynamicLists.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithDynamicLists<\/a> kommt die 10 in den folgenden Methoden vor:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getNumberOfDigits<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> number)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> numberOfDigits = <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">while<\/span> (number &gt;= <span class=\"hljs-number\">10<\/span>) {\n    number \/= <span class=\"hljs-number\">10<\/span>;\n    numberOfDigits++;\n  }\n  <span class=\"hljs-keyword\">return<\/span> numberOfDigits;\n}\n\n<span class=\"hljs-keyword\">private<\/span> Bucket&#091;] createBuckets() {\n  Bucket&#091;] buckets = <span class=\"hljs-keyword\">new<\/span> Bucket&#091;<span class=\"hljs-number\">10<\/span>];\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; <span class=\"hljs-number\">10<\/span>; i++) {\n    buckets&#091;i] = <span class=\"hljs-keyword\">new<\/span> Bucket();\n  }\n  <span class=\"hljs-keyword\">return<\/span> buckets;\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">distributeToBuckets<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex, Bucket&#091;] buckets)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n    <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % <span class=\"hljs-number\">10<\/span>;\n    buckets&#091;digit].add(element);\n  }\n}\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">calculateDivisor<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n  <span class=\"hljs-keyword\">int<\/span> divisor = <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; digitIndex; i++) {\n    divisor *= <span class=\"hljs-number\">10<\/span>;\n  }\n  <span class=\"hljs-keyword\">return<\/span> divisor;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Wir k\u00f6nnen die 10 an all diesen Stellen durch eine andere Basis ersetzen. Besser noch: Wir ersetzen sie durch eine Variable, so dass wir den Sortieralgorithmus mit jeder beliebigen Basis aufrufen k\u00f6nnen.<\/p>\n\n\n\n<p>In der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithDynamicListsAndCustomBase.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithDynamicListsAndCustomBase<\/a> findest du die entsprechende Anpassung:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">RadixSortWithDynamicListsAndCustomBase<\/span> <span class=\"hljs-keyword\">implements<\/span> <span class=\"hljs-title\">SortAlgorithm<\/span> <\/span>{\n\n  <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-keyword\">int<\/span> base;\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">RadixSortWithDynamicListsAndCustomBase<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> base)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">this<\/span>.base = base;\n  }\n\n  <span class=\"hljs-comment\">\/\/ All methods not printed here are the same as in RadixSortWithDynamicLists<\/span>\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">getNumberOfDigits<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> number)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> numberOfDigits = <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">while<\/span> (number &gt;= base) {\n      number \/= base;\n      numberOfDigits++;\n    }\n    <span class=\"hljs-keyword\">return<\/span> numberOfDigits;\n  }\n\n  <span class=\"hljs-keyword\">private<\/span> Bucket&#091;] createBuckets() {\n    Bucket&#091;] buckets = <span class=\"hljs-keyword\">new<\/span> Bucket&#091;base];\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; base; i++) {\n      buckets&#091;i] = <span class=\"hljs-keyword\">new<\/span> Bucket();\n    }\n    <span class=\"hljs-keyword\">return<\/span> buckets;\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">distributeToBuckets<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span>&#091;] elements, <span class=\"hljs-keyword\">int<\/span> digitIndex, Bucket&#091;] buckets)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> divisor = calculateDivisor(digitIndex);\n\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> element : elements) {\n      <span class=\"hljs-keyword\">int<\/span> digit = element \/ divisor % base;\n      buckets&#091;digit].add(element);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">int<\/span> <span class=\"hljs-title\">calculateDivisor<\/span><span class=\"hljs-params\">(<span class=\"hljs-keyword\">int<\/span> digitIndex)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> divisor = <span class=\"hljs-number\">1<\/span>;\n    <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">int<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; digitIndex; i++) {\n      divisor *= base;\n    }\n    <span class=\"hljs-keyword\">return<\/span> divisor;\n  }\n\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Beachte bitte, dass im GitHub-Repository die Methoden <code>getNumberOfDigits()<\/code> und <code>calculateDivisor()<\/code> in die Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortHelper.java\" target=\"_blank\" rel=\"noopener\">RadixSortHelper<\/a> ausgelagert sind, da sie auch von anderen Radix-Sort-Implementierungen ben\u00f6tigt werden.<\/p>\n\n\n\n<p>Im GitHub-Repository findest du au\u00dferdem die angepassten Algorithmen f\u00fcr Arrays, Counting Sort und rekursives MSD Radix Sort:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dynamische Listen + variable Basis: <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithDynamicListsAndCustomBase.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithDynamicListsAndCustomBase<\/a> <\/li>\n\n\n\n<li>Arrays + variable Basis: <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithArraysAndCustomBase.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithArraysAndCustomBase<\/a> <\/li>\n\n\n\n<li>Counting Sort + variable Basis: <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RadixSortWithCountingSortAndCustomBase.java\" target=\"_blank\" rel=\"noopener\">RadixSortWithCountingSortAndCustomBase<\/a> <\/li>\n\n\n\n<li>Rekursives MSD Radix Sort + variable Basis: <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RecursiveMsdRadixSortWithArraysAndCustomBase.java\" target=\"_blank\" rel=\"noopener\">RecursiveMsdRadixSortWithArraysAndCustomBase<\/a> <\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-zeitkomplexitaet\">Radix Sort Zeitkomplexit\u00e4t<\/h2>\n\n\n\n<p>In diesem Kapitel zeige ich dir, wie du die Zeitkomplexit\u00e4t von Radix Sort bestimmst. Eine Einf\u00fchrung in das Thema Zeitkomplexit\u00e4t findest du im Artikel \"<a href=\"\/de\/algorithmen\/o-notation-zeitkomplexitaet\/\">Zeitkomplexit\u00e4t\" und \"O-Notation<\/a>\".<\/p>\n\n\n\n<p>Wir verwenden im Folgenden die folgenden Variablen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>n<\/em> = die Anzahl der zu sortierenden Elemente<\/li>\n\n\n\n<li><em>k<\/em> = die maximale Schl\u00fcssell\u00e4nge (\"key length\", Anzahl der Stellen) der zu sortierenden Elemente<\/li>\n\n\n\n<li><em>b<\/em> = die Basis (= die Anzahl der Buckets)<\/li>\n<\/ul>\n\n\n\n<p>Der Algorithmus iteriert \u00fcber <em>k<\/em> Stellen; f\u00fcr jede Stelle betreibt er den folgenden Aufwand:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Er legt <em>b<\/em> Buckets an. Der Aufwand daf\u00fcr ist jeweils konstant.<\/li>\n\n\n\n<li>Er iteriert \u00fcber alle <em>n<\/em> Elemente, um diese in die Buckets einzusortieren. Der Aufwand f\u00fcr die Berechnung der Bucket-Nummer und f\u00fcr das Einf\u00fcgen in den Bucket ist konstant.<\/li>\n\n\n\n<li>Er iteriert \u00fcber <em>b<\/em> Buckets und entnimmt diesen wieder insgesamt <em>n<\/em> Elemente. Der Aufwand f\u00fcr jeden dieser Schritte ist wiederum konstant.<\/li>\n<\/ul>\n\n\n\n<p>Konstante Aufw\u00e4nde vernachl\u00e4ssigen wir bei der Bestimmung der Zeitkomplexit\u00e4t. Somit ergibt sich:<\/p>\n\n\n\n<p class=\"has-text-align-center has-background\" style=\"background-color:#e7f2f8\">Die Zeitkomplexit\u00e4t f\u00fcr Radix Sort ist: <em>O(k&nbsp;\u00b7&nbsp;(b&nbsp;+&nbsp;n))<\/em><\/p>\n\n\n\n<p>Der Aufwand ist unabh\u00e4ngig davon, wie die Eingabezahlen angeordnet sind. Ob diese zuf\u00e4llig verteilt oder bereits vorsortiert sind, macht keinen Unterschied f\u00fcr den Algorithmus. Best case, average case und worst case sind also identisch.<\/p>\n\n\n\n<p>Die Formel sieht erstmal kompliziert aus. Doch zwei der drei Variablen sind in den meisten F\u00e4llen gar nicht variabel. Wenn wir z. B. Longs mit der Basis 10 sortieren, k\u00f6nnen wir <em>k<\/em> durch 19 ersetzen (der maximal m\u00f6gliche Wert f\u00fcr ein Long ist 9.223.372.036.854.775.807) und <em>b<\/em> durch 10. <\/p>\n\n\n\n<p>Die Formel wird dann zu <em>O(19 \u00b7 (10 + n))<\/em>. Konstanten k\u00f6nnen wir weglassen, somit ergibt sich:<\/p>\n\n\n\n<p class=\"has-text-align-center has-background\" style=\"background-color:#e7f2f8\">Die Zeitkomplexit\u00e4t f\u00fcr Radix Sort <br>bei bekannter maximaler L\u00e4nge der zu sortierenden Elemente <br>und mit festgelegter Basis ist: <em>O(n)<\/em><\/p>\n\n\n\n<p>Radix Sort hat also f\u00fcr primitive Datentypen wie Integer und Long (bei diesen kennen wir die maximale L\u00e4nge) eine bessere Zeitkomplexit\u00e4t als <a href=\"\/de\/algorithmen\/quicksort\/#Quicksort_Zeitkomplexitat\">Quicksort<\/a>! <\/p>\n\n\n\n<p>Ob Radix Sort tats\u00e4chlich schneller ist, erf\u00e4hrst du im n\u00e4chsten Kapitel. Dort werden wir die Laufzeit der verschiedenen Radix-Sort-Implementierungen messen und untereinander (und auch mit Quicksort) vergleichen.<\/p>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"5c918c0177\" src=\"https:\/\/happycoders.kit.com\/5c918c0177\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-laufzeit\">Radix Sort Laufzeit<\/h2>\n\n\n\n<p>In diesem Kapitel zeige ich dir die Ergebnisse einiger Performance-Tests, die ich mit den Tools <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/demos\/UltimateTest.java\" target=\"_blank\" rel=\"noopener\">UltimateTest<\/a> und <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/demos\/comparisons\/CompareRadixSorts.java\">CompareRadixSorts<\/a> durchgef\u00fchrt habe, um die Performance der verschiedenen Algorithmen, Implementierungen und Basen zu vergleichen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"laufzeit-verschiedener-radix-sort-implementierungen\">Laufzeit verschiedener Radix-Sort-Implementierungen<\/h3>\n\n\n\n<p>Das erste Diagramm zeigt den Vergleich der verschiedenen Implementierungen:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-800x506.png\" alt=\"Laufzeit verschiedener Radix-Sort-Implementierungen\" class=\"wp-image-32021\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radis-sort-runtime-comparison-algorithms.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Die Implementierung mit dynamischen Listen schneidet, wie vermutet, am schlechtesten ab. Die restlichen drei Varianten liefern sich ein Kopf-an-Kopf-Rennen, das die Implementierung mit Counting Sort knapp gewinnt, dicht gefolgt von der Implementierung mit Arrays.<\/p>\n\n\n\n<p>Sehr sch\u00f6n zu sehen ist auch die jeweils lineare Laufzeit <em>O(n)<\/em>, die wir im vorangegangenen Kapitel vorhergesagt hatten.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"auswirkung-der-basis-auf-die-laufzeit\">Auswirkung der Basis auf die Laufzeit<\/h3>\n\n\n\n<p>Das zweite Diagramm zeigt, wie sich die Wahl der Basis auf die Laufzeit der Array-Implementierung auswirkt:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-800x506.png\" alt=\"Auswirkung der Basis auf die Radix-Sort-Laufzeit\" class=\"wp-image-32053\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-n-and-base.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Wir k\u00f6nnen sehen, dass die Laufzeit bei einer Basis von 100 und 1.000 deutlich besser ist als bei kleineren als auch gr\u00f6\u00dferen Basen.<\/p>\n\n\n\n<p>Untersuchen wir das etwas detaillierter... Das dritte Diagramm zeigt feinere Abstufungen der Basen bei gleicher Anzahl Elemente (<em>n<\/em> = 5,555,555):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-800x506.png\" alt=\"Auswirkung der Basis auf die Radix-Sort-Laufzeit\" class=\"wp-image-32055\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-runtime-comparison-bases.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Sowohl eine zu kleine als auch eine zu gro\u00dfe Basis sind schlecht f\u00fcr die Performance.<\/p>\n\n\n\n<p>Eine sehr kleine Basis f\u00fchrt dazu, dass viele Iterationen durchgef\u00fchrt werden m\u00fcssen. Eine zu gro\u00dfe Basis f\u00fchrt zwar zu weniger Iterationen, aber deutlich mehr Buckets innerhalb der Iterationen.<\/p>\n\n\n\n<p>Ein Sweetspot zeigt sich bei einer Basis von 256.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-vs-quicksort\">Radix Sort vs. Quicksort<\/h3>\n\n\n\n<p>In folgendem Diagramm siehst du die Laufzeiten...<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>der Radix-Sort-Array-Implementierung mit einer Basis von 256,<\/li>\n\n\n\n<li>von Dual-Pivot Quicksort kombiniert mit Insertion Sort (die schnellste Variante, die wir im <a href=\"\/de\/algorithmen\/quicksort\/#Vergleich_aller_Quicksort-Optimierungen\">Quicksort-Tutorial<\/a> ermittelt haben)<\/li>\n\n\n\n<li>und der JDK-Sortiermethode <code>Arrays.sort()<\/code>, welche ebenfalls ein optimiertes Dual-Pivot Quicksort implementiert.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-800x506.png\" alt=\"Radix Sort vs. Quicksort\" class=\"wp-image-32056\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-vs-quicksort.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Und tats\u00e4chlich ist Radix Sort nicht nur in der Theorie schneller \u2013 <em>O(n)<\/em> vs. <em>O(n log n)<\/em> \u2013 sondern auch in der Praxis \u2013 und zwar sowohl im Vergleich mit dem selbst implementierten Quicksort als auch mit der noch schnelleren JDK-Quicksort-Implementierung <code>Arrays.sort()<\/code>.<\/p>\n\n\n\n<p>Wenn du also <code>int<\/code>-Primitive sortieren musst und die Performance kritisch ist, solltest du erw\u00e4gen statt des Java-Hausmittels <code>Arrays.sort()<\/code> besser Radix-Sort einzusetzen. Du kannst gerne die Implementierung aus diesem Artikel verwenden.<\/p>\n\n\n\n<p>F\u00fcr <code>long<\/code>-Primitive gilt das nicht, hier ist <code>Arrays.sort()<\/code> etwa 50% schneller als meine Radix-Sort-Implementierung.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"weitere-eigenschaften-von-radix-sort\">Weitere Eigenschaften von Radix Sort<\/h2>\n\n\n\n<p>In diesem abschlie\u00dfenden Kapitel betrachten wir die Platzkomplexit\u00e4t, Stabilit\u00e4t und Parallelisierbarkeit von Radix Sort, sowie die Unterschiede zu Counting Sort und Bucket Sort.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-platzkomplexitaet\">Radix Sort Platzkomplexit\u00e4t<\/h3>\n\n\n\n<p>Alle hier gezeigten Varianten ben\u00f6tigen zus\u00e4tzlichen Speicherplatz:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>O(b)<\/em> f\u00fcr das Z\u00e4hlen der Ziffern (nicht ben\u00f6tigt in der Variante mit dynamischen Listen)<\/li>\n\n\n\n<li><em>O(b)<\/em> f\u00fcr die Referenzen auf die Buckets (nicht ben\u00f6tigt bei der Counting-Sort-Variante)<\/li>\n\n\n\n<li><em>O(n)<\/em> f\u00fcr die Buckets (nicht ben\u00f6tigt bei der Counting-Sort-Variante)<\/li>\n\n\n\n<li><em>O(n)<\/em> f\u00fcr ein zus\u00e4tzliches Ziel-Array (nur bei der Counting-Sort-Variante)<\/li>\n<\/ul>\n\n\n\n<p>Jede Variante enth\u00e4lt also mindestens einen <em>O(b)<\/em>-Anteil und mindestens einen <em>O(n)<\/em>-Anteil.<\/p>\n\n\n\n<p>Somit gilt:<\/p>\n\n\n\n<p class=\"has-text-align-center has-background\" style=\"background-color:#e7f2f8\">Die Platzkomplexit\u00e4t von Radix Sort ist: <em>O(b&nbsp;+&nbsp;n)<\/em><\/p>\n\n\n\n<p>Es gibt eine Ausnahme: Rekursives MSD Radix Sort mit der Basis 2 kann ohne zus\u00e4tzlichen Speicher f\u00fcr die Elemente auskommen, indem diese derart partitioniert werden, dass durch jeweiligen Austausch zweier Elemente alle Elemente, deren Bit an der gerade betrachteten Stelle auf 1 steht, an den rechten Rand geschoben werden und alle Elemente, deren Bit auf 0 steht, an den linken Rand (\u00e4hnlich wie bei Quicksort).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"ist-radix-sort-stabil\">Ist Radix Sort stabil?<\/h3>\n\n\n\n<p>Die <a href=\"https:\/\/www.happycoders.eu\/de\/algorithmen\/sortieralgorithmen\/#Stabile_und_nicht-stabile_Sortierverfahren\">Bedeutung von Stabilit\u00e4t bei Sortierverfahren<\/a> kannst du im verlinkten Einf\u00fchrungsartikel nachlesen. Kurz gesagt: Elemente mit dem gleichen Schl\u00fcssel behalten bei der Sortierung ihre urspr\u00fcngliche Reihenfolge zueinander bei.<\/p>\n\n\n\n<p>Alle in diesem Artikel gezeigten Implementierungen von Radix Sort sind stabil.<\/p>\n\n\n\n<p>Die im vorherigen Abschnitt angesprochene In-Place-MSD-Radix-Sort-Variante ist hingegen nicht stabil (analog zu Quicksort).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"paralleles-radix-sort\">Paralleles Radix Sort<\/h3>\n\n\n\n<p>Beide Radix-Sort-Varianten (LSD und MSD) lassen sich parallelisieren.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">MSD Radix Sort parallel<\/h4>\n\n\n\n<p>Bei MSD Radix Sort k\u00f6nnen wir nach der ersten Partitionierungsphase alle entstandenen Buckets unabh\u00e4ngig voneinander parallel sortieren. Dank paralleler Streams l\u00e4sst sich das in Java sehr einfach implementieren:<\/p>\n\n\n\n<p>Hier noch einmal der entsprechende sequentielle Code aus der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/RecursiveMsdRadixSortWithArrays.java\" target=\"_blank\" rel=\"noopener\">RecursiveMsdRadixSortWithArrays<\/a>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">for<\/span> (Bucket bucket : buckets) {\n  <span class=\"hljs-keyword\">if<\/span> (bucket.needsToBeSorted()) {\n    sortByDigit(bucket.getElements(), digitIndex - <span class=\"hljs-number\">1<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Und hier die parallelisierte Variante (Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/ParallelRecursiveMsdRadixSortWithArrays.java\" target=\"_blank\" rel=\"noopener\">ParallelRecursiveMsdRadixSortWithArrays<\/a> im GitHub-Repository):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\">Arrays.stream(buckets)\n    .parallel()\n    .forEach(\n        bucket -&gt; {\n          <span class=\"hljs-keyword\">if<\/span> (bucket.needsToBeSorted()) {\n            sortByDigit(bucket.getElements(), digitIndex - <span class=\"hljs-number\">1<\/span>);\n          }\n        });<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">LSD Radix Sort parallel<\/h4>\n\n\n\n<p>Um LSD Radix Sort zu parallelisieren, m\u00fcssen wir etwas mehr Aufwand betreiben:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Wir teilen das Eingabe-Array in parallel zu bearbeitende Segmente auf (z. B. entsprechend der Anzahl der CPU-Kerne).<\/li>\n\n\n\n<li>Wir berechnen parallel pro Segment, wie viele Elemente in welche Buckets sortiert werden m\u00fcssen.<\/li>\n\n\n\n<li>Wenn Schritt 2 f\u00fcr alle Segmente abgeschlossen ist, berechnen wir a) pro Bucket die Gesamtanzahl der Elemente und b) pro Segment die Start-Schreibpositionen f\u00fcr jeden Bucket.<\/li>\n\n\n\n<li>Wir verteilen die Elemente der Segmente parallel auf die Buckets. Durch die in Schritt 3 berechneten Start-Schreibpositionen wissen wir, an welchen Positionen innerhalb der Buckets wir aus welchen Segmenten schreiben d\u00fcrfen.<\/li>\n\n\n\n<li>Wenn Schritt 4 f\u00fcr alle Segmente abgeschlossen ist, berechnen wir pro Bucket den Offset im Zielarray (als Pr\u00e4fixsummen \u00fcber die Anzahl der Elemente der Buckets).<\/li>\n\n\n\n<li><span style=\"color: initial;\">Wir sammeln die Elemente der Buckets parallel ein. Durch die in Schritt 5 berechneten Offsets wissen wir, an welcher Position im Zielarray die Elemente eines Buckets starten m\u00fcssen.<\/span><\/li>\n<\/ol>\n\n\n\n<p>Den Quellcode findest du in der Klasse <a href=\"https:\/\/github.com\/SvenWoltmann\/sorting-algorithms-ultimate-guide\/blob\/main\/src\/main\/java\/eu\/happycoders\/sort\/method\/radixsort\/ParallelRadixSortWithArrays.java\" target=\"_blank\" rel=\"noopener\">ParallelRadixSortWithArrays<\/a> im GitHub-Repo. Die sechs oben aufgez\u00e4hlten Schritte sind im Code mit entsprechend nummerierten Kommentaren markiert.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Radix Sort parallel vs. sequentiell<\/h4>\n\n\n\n<p>Das folgende Diagramm zeigt die Laufzeit der parallelen Varianten verglichen mit den sequentiellen Varianten auf einer 6-Kern-i7-CPU:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-800x506.png\" alt=\"Radix Sort Laufzeit - parallel vs. sequentiell\" class=\"wp-image-32044\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Die parallelen Varianten sind bei 67 Millionen Elementen nur etwa 2,3 mal schneller. Dass Faktor 6 nicht einmal ann\u00e4hernd erreicht wird, liegt zum einen daran, dass Teile des Codes nicht parallel ausgef\u00fchrt werden k\u00f6nnen und zum anderen daran, dass die CPU-Kerne sehr viele Daten mit dem Arbeitsspeicher austauschen m\u00fcssen (das Eingabearray belegt 1 GB).<\/p>\n\n\n\n<p>Wenn wir uns einen kleineren Ausschnitt des Diagramms anschauen, sieht die Sache anders aus:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"506\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-800x506.png\" alt=\"Radix Sort Laufzeit - parallel vs. sequentiell f\u00fcr kleine n\" class=\"wp-image-32050\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-800x506.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-224x142.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-336x213.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-504x319.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-672x425.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-400x253.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-600x380.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-944x597.png 944w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n-1200x759.png 1200w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/parallel-radix-sort-runtime-small-n.png 1600w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure>\n<\/div>\n\n\n<p>Bei einer halben Million Elemente ist das parallele Radix Sort mit Arrays 5,75 mal schneller als die sequentielle Variante. Die CPU-Kerne werden also nahezu komplett ausgenutzt. Das liegt daran, dass das Eingabearray nur noch 2 MB gro\u00df ist, und die Sortierung somit komplett im L3-Cache der CPU stattfinden kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-vs-counting-sort\">Radix Sort vs. Counting Sort<\/h3>\n\n\n\n<p>Beide Sortierverfahren verwenden Buckets zum Sortieren. Bei Counting Sort ben\u00f6tigen wir einen Bucket f\u00fcr <em>jeden<\/em> Wert. Wollten wir beispielsweise Integers sortieren, br\u00e4uchten wir etwa vier Milliarden Buckets. Bei Radix Sort hingegen entspricht die Anzahl der Buckets der gew\u00e4hlten Basis.<\/p>\n\n\n\n<p>Bei Radix Sort sortieren wir iterativ Ziffer f\u00fcr Ziffer; bei Counting Sort sortieren wir die Elemente in einer einzigen Iteration.<\/p>\n\n\n\n<p>Counting Sort eignet sich daher in erster Linie f\u00fcr kleine Zahlenr\u00e4ume.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"radix-sort-vs-bucket-sort\">Radix Sort vs. Bucket Sort<\/h3>\n\n\n\n<p>Bei Bucket Sort werden die Elemente zun\u00e4chst so auf eine vorgegebene Anzahl Buckets verteilt, dass alle Elemente eines Buckets gr\u00f6\u00dfer sind als alle Elemente des vorherigen Buckets (z. B. 0-99, 100-199, 200-299, usw.).<\/p>\n\n\n\n<p>Danach wird jeder Bucket in sich sortiert \u2013 entweder rekursiv mit Bucket Sort oder mit einem anderen Sortierverfahren \u2013 mit welchem genau ist nicht spezifiziert. Abschlie\u00dfend werden die Elemente aus den sortierten Buckets aneinandergereiht.<\/p>\n\n\n\n<p>Falls dir das bekannt vorkommt \u2013 eine Form von Bucket Sort hast du in diesem Artikel kennengelernt: das <a href=\"#msd-radix-sort\">rekursive MSD Radix Sort<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"zusammenfassung\">Zusammenfassung<\/h2>\n\n\n\n<p>Radix Sort ist ein stabiler Sortieralgorithmus mit einer allgemeinen Zeitkomplexit\u00e4t von <em>O(k \u00b7 (b + n))<\/em>, wobei <em>k<\/em> f\u00fcr die maximale Schl\u00fcssell\u00e4nge (\"key length\") der zu sortierenden Elemente steht und <em>b<\/em> f\u00fcr die Basis.<\/p>\n\n\n\n<p>Ist die maximale L\u00e4nge der zu sortierenden Elemente bekannt und die Basis festgelegt, dann betr\u00e4gt die Zeitkomplexit\u00e4t <em>O(n)<\/em>.<\/p>\n\n\n\n<p>F\u00fcr Integers ist Radix Sort schneller als Quicksort (zumindest auf meiner Testumgebung). Solltest du zeitkritische Sortiervorg\u00e4nge in Java implementieren m\u00fcssen, empfehle ich dir <code>Arrays.sort()<\/code> mit einer Implementierung von Radix Sort zu vergleichen.<\/p>\n\n\n\n<p>Weitere Sortieralgorithmen findest du in der <a href=\"\/de\/algorithmen\/sortieralgorithmen\/#Vergleich_der_wichtigsten_Sortieralgorithmen\">\u00dcbersicht aller Sortieralgorithmen und ihrer Eigenschaften<\/a> im ersten Teil der Artikelserie.<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>M\u00f6chtest du auf dem Laufenden bleiben und informiert werden, wenn neue Artikel auf HappyCoders.eu ver\u00f6ffentlicht werden? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>Wie funktioniert Radix Sort? Wie implementiert man Radix Sort in Java? Welche Zeit- und Platzkomplexit\u00e4t hat Radix Sort?<\/p>\n","protected":false},"author":1,"featured_media":31837,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"none","_seopress_titles_title":"","_seopress_titles_desc":"Wie funktioniert Radix Sort? Wie implementiert man Radix Sort in Java? Welche Zeit- und Platzkomplexit\u00e4t hat Radix Sort?","_seopress_robots_index":"","_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":35735,"_post_count":0,"footnotes":""},"categories":[127],"tags":[129],"class_list":["post-31807","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algorithmen","tag-sortieralgorithmen"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2022\/07\/radix-sort-1770x986-1.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"Wie funktioniert Radix Sort? Wie implementiert man Radix Sort in Java? Welche Zeit- und Platzkomplexit\u00e4t hat Radix Sort?","public_identification_id":"081be3b8d2fd4a98b53d612570b3740d","private_identification_id":"846ccd8a530f4935ac69e64746a1ec89","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/31807","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=31807"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/31807\/revisions"}],"predecessor-version":[{"id":52519,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/31807\/revisions\/52519"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/31837"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=31807"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=31807"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=31807"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}