www.wikidata.de-de.nina.az
Heapsort Haldensortierung ist ein in den 1960ern von Robert W Floyd und J W J Williams entwickeltes Sortierverfahren Seine Komplexitat ist bei einem Array der Lange n displaystyle n in der Landau Notation ausgedruckt in O n log n displaystyle mathcal O n cdot log n und ist damit asymptotisch optimal fur Sortieren per Vergleich Heapsort arbeitet zwar in place ist jedoch nicht stabil Der Heapsort Algorithmus verwendet einen binaren Heap als zentrale Datenstruktur Heapsort kann als eine Verbesserung von Selectionsort verstanden werden und ist mit Treesort verwandt Der Heapsort Algorithmus beim Sortieren eines Arrays aus permutierten Werten Der Algorithmus besteht aus zwei Schritten im vorbereitenden Schritt wird das Array zu einem binaren Heap umgeordnet dessen Baumstruktur vor dem eigentlichen Sortierschritt kurz eingeblendet wird Inhaltsverzeichnis 1 Beschreibung 2 Beispiel 3 Effizienz 4 Abgrenzung 5 Bottom Up Heapsort 5 1 Prinzip der Sortierung 5 2 Algorithmus 5 3 Beispiel 5 4 Implementierung 6 Andere Varianten 6 1 Smoothsort 6 2 Ternare Heaps 6 3 n are Heaps 7 Siehe auch 8 Literatur 9 Weblinks 10 EinzelnachweiseBeschreibung BearbeitenDie Eingabe ist ein Array mit zu sortierenden Elementen Als erstes wird die Eingabe in einen binaren Max Heap uberfuhrt Aus der Heap Eigenschaft folgt direkt dass nun an der ersten Array Position das grosste Element steht Dieses wird mit dem letzten Array Element vertauscht und die Heap Array Grosse um 1 verringert ohne den Speicher freizugeben Die neue Wurzel des Heaps kann die Heap Eigenschaft verletzen Die Heapify Operation korrigiert gegebenenfalls den Heap so dass nun das nachstgrossere bzw gleich grosse Element an der ersten Array Position steht Die Vertausch Verkleiner und Heapify Schritte werden so lange wiederholt bis die Heap Grosse 1 ist Danach enthalt das Eingabe Array die Elemente in aufsteigend sortierter Reihenfolge In Pseudocode heapsort Array A build A assert isHeap A 0 tmp A size while A size gt 1 A swap 0 A size 1 A size A size 1 heapify A assert isHeap A 0 A size tmp assert isSorted A Bei einer Sortierung in absteigender Reihenfolge wird statt des Max Heaps ein Min Heap verwendet In einem Min Heap steht an erster Stelle das kleinste Element Gemass der Definition von einem binaren Heap wird die Abfolge der Elemente in einem Heap durch eine Vergleichsoperation siehe Ordnungsrelation bestimmt die eine totale Ordnung auf den Elementen definiert In einem Min Heap ist das die lt displaystyle lt nbsp Relation und in einem Max Heap die gt displaystyle gt nbsp Relation Der Pseudocode abstrahiert von der Vergleichsoperation Die zu sortierenden Elemente werden auch als Schlussel bezeichnet Pro Index Position kann das Eingabe Array mehrere Datenkomponenten enthalten In dem Fall muss eine Komponente als Sortierschlussel definiert werden auf der die Vergleichsoperation arbeitet Die Vertauschoperation vertauscht komplette Array Eintrage Die assert Operation im Pseudocode dokumentiert welche Eigenschaften das Array nach welchen Algorithmus Schritten korrekterweise erfullt bzw erfullen muss Beispiel Bearbeiten nbsp Ein Beispiel fur Heapsort an einer ZahlenfolgeIn der Abbildung wird die Sortierung der Beispielzahlenfolge 23 1 6 19 14 18 8 24 15 mit dem Heapsort Algorithmus dargestellt Die einzelnen Teilbilder sind von links nach rechts und von oben nach unten chronologisch angeordnet Im ersten Teilbild ist die unsortierte Eingabe und im letzten die sortierte Ausgabe abgebildet Der Ubergang vom ersten zum zweiten Teilbild entspricht der Heapifizierung des Eingabe Arrays Die an einer Swap Operation beteiligten Elemente sind rot und mit unterbrochenen Pfeilen markiert dicke Doppelpfeile bezeichnen die an einer Heapify Operation beteiligten Elemente und grun markierte Elemente zeigen den schon sortierten Anteil des Arrays an Die Element Indizes sind mit kleinen schwarzen Knoten eingezeichnet jeweils links unten von dem Element Wert Eine blaue Hinterlegung der Array Elemente indiziert die Laufzeit der Heapsort Prozedur Die Indizes entsprechen einer aufsteigenden Nummerierung nach Level Order beginnend mit 0 In einer Implementierung des Algorithmus ist die Baumstruktur implizit und das Array der Elemente zusammenhangend was durch die Platzierung der Element Indizes in der Abbildung angedeutet wird Effizienz BearbeitenMan kann zeigen dass der Aufbau des Heaps in Landau Notation ausgedruckt in O n displaystyle mathcal O n nbsp Schritten ablaufen kann In einem grossen zufallig verteilten Datenfeld 100 bis 1010 Datenelemente sind durchschnittlich mehr als 4 aber weniger als 5 signifikante Sortieroperationen pro Element notig 2 5 Datenvergleiche und 2 5 Zuweisungen Dies liegt daran dass ein zufalliges Element mit exponentiell zunehmender Wahrscheinlichkeit einen geeigneten Vaterknoten findet 60 85 93 97 Die Heapify Operation benotigt im ungunstigsten Fall 8 log n displaystyle Theta log n nbsp Schritte Dies ist bei exakt inverser Reihenfolge der Fall In dem durchschnittlichen Fall werden etwa die Halfte der Operationen des ungunstigsten Falls und somit ebenfalls 8 log n displaystyle Theta log n nbsp Schritte benotigt Gunstig ist nur ein Feld dessen Elemente fast alle den gleichen Wert haben Sind aber nur weniger als ca 80 der Daten identisch dann entspricht die Laufzeit bereits dem durchschnittlichen Fall Eine vorteilhafte Anordnung von Daten mit mehreren verschiedenen Werten ist prinzipbedingt unmoglich da dies der Heapcharakteristik widerspricht Den Worst Case stellen mit 8 n log n displaystyle Theta n cdot log n nbsp weitgehend vorsortierte Daten dar weil der Heapaufbau de facto eine schrittweise vollstandige Invertierung der Sortierreihenfolge darstellt Der gunstigste aber unwahrscheinliche Fall ist ein bereits umgekehrt sortiertes Datenfeld 1 Vergleich pro Element keine Zuweisung Gleiches gilt wenn fast alle Daten identisch sind Auf heterogenen Daten vorsortiert oder nicht dominiert Heapify mit wenigstens uber 60 der Zeit meistens uber 80 Somit garantiert Heapsort eine Gesamtlaufzeit von O n log n displaystyle mathcal O n cdot log n nbsp Auch im besten Fall wird eine Laufzeit von 8 n log n displaystyle Theta n cdot log n nbsp benotigt 1 2 Eine Variante von Heapsort benotigt im Worst Case n log 2 n n log 2 log 2 n n displaystyle n cdot log 2 n n cdot log 2 log 2 n n nbsp Vergleiche 3 Abgrenzung BearbeitenIm Durchschnitt ist Heapsort nur dann schneller als Quicksort wenn Vergleiche auf den zu sortierenden Daten sehr aufwendig sind und gleichzeitig eine fur Quicksort ungunstige Datenanordnung besteht z B viele gleiche Elemente In der Praxis ist bei unsortierten oder teilweise vorsortierten Daten Quicksort oder Introsort um einen konstanten Faktor von 2 bis 5 schneller als Heapsort Dies wird jedoch kontrovers diskutiert und es gibt Analysen die Heapsort vorne sehen sowohl aus Implementierungs wie auch aus informationstheoretischen Uberlegungen 4 5 Allerdings spricht das Worst Case Verhalten von O n log n displaystyle mathcal O n cdot log n nbsp gegenuber 8 n 2 displaystyle Theta n 2 nbsp bei Quicksort fur Heapsort Introsort ist dagegen in fast allen Fallen schneller als Heapsort lediglich in entarteten Fallen 20 bis 30 langsamer Bottom Up Heapsort BearbeitenDie wichtigste Variante des Heapsort Algorithmus ist Bottom Up Heapsort das haufig fast die Halfte der notigen Vergleichsoperationen einsparen kann und sich folglich besonders da rentiert wo Vergleiche aufwendig sind Bottom Up Heapsort ist ein Sortieralgorithmus der u a 1990 von Ingo Wegener vorgestellt wurde und im Durchschnitt besser als Quicksort arbeitet falls man Vergleichsoperationen hinreichend stark gewichtet Es ist eine Variante von Heapsort die vor allem zur Sortierung sehr grosser Datenmengen geeignet ist wenn im Vergleich zu den notwendigen Vertauschungsoperationen ein relativ hoher Aufwand pro Vergleichsoperation erforderlich ist Diese Variante wurde allerdings bereits 1986 von Svante Carlsson analysiert der letztlich eine weitere Variante fand die sogar eine Worst Case Laufzeit von nur n log 2 n O n log 2 log 2 n displaystyle n cdot log 2 n mathcal O n cdot log 2 log 2 n nbsp Vergleichen hat Entdeckt wurde dieser Bottom Up Heapsort bereits von Robert W Floyd der aber das Laufzeitverhalten dieser Variante nicht beweisen konnte Bottom Up Heapsort benotigt zum Sortieren einer Folge von n displaystyle n nbsp Elementen im Worst Case 3 2 n log 2 n 2 n displaystyle tfrac 3 2 cdot n cdot log 2 n 2 cdot n nbsp Vergleiche Im Durchschnitt sind es n log 2 n O n displaystyle n cdot log 2 n mathcal O n nbsp Vergleiche Prinzip der Sortierung Bearbeiten Beim Sortieren mit normalem Heapsort finden beim Absenken eines Elements zwei Vergleiche pro Ebene statt Welcher der beiden Nachfolgeknoten des abzusenkenden Elements ist grosser Ist der nun bestimmte Nachfolgeknoten grosser als das abzusenkende Element Nachdem ein Binarbaum zur Halfte aus Blattern besteht und zudem beim Sortieren ehemalige Blatter mit ohnehin schon eher niedrigen Werten abgesenkt werden ist es wahrscheinlich dass ein Element bis zur Blattebene oder in deren Nahe abgesenkt werden muss Deshalb kann es lohnend sein auf den zweiten Vergleich zu verzichten und auf Verdacht bis zur Blattebene abzusenken In einem zweiten Schritt wird dann ruckwarts uberpruft wie weit das Element wieder angehoben werden muss Im gunstigsten Fall sehr grosse Felder mit nur wenigen Dubletten kann dabei fast die Halfte der insgesamt notigen Vergleiche bei massigem Zusatzaufwand eingespart werden Weniger geeignet ist Bottom Up Heapsort zur Sortierung kleinerer Felder mit einfacher numerischer Vergleichsoperation und dann wenn im Feld sehr viele Elemente gleichwertig sind Dann stimmt die Annahme nicht dass meist bis in die Nahe der Blattebene abgesenkt werden muss Algorithmus Bearbeiten Konkret wird der Heapsort Algorithmus was das Absenken betrifft wie folgt verandert Zunachst wird der Pfad in welchem das Wurzelelement versenkt werden soll bestimmt Dies geschieht durch die Ermittlung des jeweils grossten Kindes Pfad maximaler Kinder Danach wird dieser bestimmte Pfad von unten nach oben vom Blatt in Richtung Wurzel durchlaufen Hierbei wird bei jedem besuchten Knoten verglichen ob er grosser als das abzusenkende Wurzelelement ist Ist dem so wird das Wurzelelement an die Position des zuletzt besuchten Knotens kopiert und vorher der restliche Pfad um eine Ebene nach oben verschoben Alternativ kann man auch die Verschiebung von vornherein auf Verdacht bis zur Blattebene durchfuhren und spater soweit notwendig wieder ruckgangig machen Wo Kopien relativ gunstig durchgefuhrt werden konnen weil etwa nur ein Zeiger kopiert wird kann das insgesamt vorteilhaft sein Beispiel Bearbeiten Heap 9 23 24 20 18 14 17 13 15 11 10 5 7 3 2 Baumstruktur 9 23 24 20 18 14 17 13 15 11 10 5 7 3 2 Das Element 9 muss abgesenkt werden da es kleiner als mindestens ein Nachfolgeknoten ist Es wird als erstes der Pfad der maximalen Kinder ausgehend von der Wurzel bestimmt Es ergibt sich also 9 24 17 3 Der Algorithmus durchlauft diesen Pfad nun von unten nach oben also 3 gt 17 gt 24 gt 9 Nun wird der Pfad vom Blattknoten 3 beginnend solange durchlaufen bis sich ein Knoten findet der grosser als 9 ist Der Durchlauf endet folglich bei 17 Nun werden alle Knoten ab 17 bis zum Nachfolgeknoten der Wurzel 17 gt 24 um eine Ebene nach oben und der Knoten 9 an die Position von 17 verschoben Folglich andern 17 und 24 als Nachfolgeknoten und 9 als Wurzelknoten ihren Platz Heap 24 23 17 20 18 14 9 13 15 11 10 5 7 3 2 Baumstruktur 24 24 23 17 9 23 17 20 18 14 lt 20 18 14 9 13 15 11 10 5 7 3 2 13 15 11 10 5 7 3 2 Implementierung BearbeitenEinfache Beispielsimplementierung in der Programmiersprache C int heapsort bu int data int n zu sortierendes Feld und seine Lange int val parent child int root n gt gt 1 erstes Blatt im Baum int count 0 Zahler fur Anzahl der Vergleiche for if root Teil 1 Konstruktion des Heaps parent root val data root zu versickernder Wert else if n Teil 2 eigentliche Sortierung val data n zu versickernder Wert vom Heap Ende data n data 0 Spitze des Heaps hinter den Heap in parent 0 den sortierten Bereich verschieben else Heap ist leer Sortierung beendet break while child parent 1 lt lt 1 lt n zweites Kind Abbruch am Ende des Heaps if count data child 1 gt data child grosseres Kind wahlen child data parent data child grosseres Kind nach oben rucken parent child in der Ebene darunter weitersuchen if child n ein einzelnes Kind am Heap Ende ist ubersprungen worden if count data child gt val grosser als der zu versick data parent data child ernde Wert also noch nach oben data child val versickerten Wert eintragen continue child parent 1 Ebene nach oben zuruck else if count data parent gt val das Blatt ist grosser als der data parent val zu versickernde Wert der damit continue direkt eingetragen werden kann child parent 1 gt gt 1 2 Ebenen nach oben zuruck while child root maximal zum Ausgangspunkt zuruck parent child 1 gt gt 1 den Vergleichswert haben wir bereits nach oben verschoben if count data parent gt val grosser als der zu versickernde break Wert also Position gefunden data child data parent Ruckverschiebung notig child parent 1 Ebene nach oben zuruck data child val versickerten Wert eintragen return count Zu Vergleichszwecken gibt die Funktion die Anzahl der durchgefuhrten Vergleiche zuruck Andere Varianten BearbeitenSmoothsort Bearbeiten Normales Heapsort sortiert bereits weitgehend vorsortierte Felder nicht schneller als andere Die grossten Elemente mussen immer erst ganz nach vorn an die Spitze des Heaps wandern bevor sie wieder nach hinten kopiert werden Smoothsort andert das indem es im Prinzip die Reihenfolge des Heaps umdreht Dabei ist allerdings betrachtlicher Aufwand notig um den Heapstatus beim Sortieren aufrechtzuerhalten Smoothsort benotigt eine lineare Laufzeit von O n displaystyle mathcal O n nbsp um ein vorsortiertes Array Best Case zu verarbeiten und genauso wie andere Varianten eine Laufzeit von O n log n displaystyle mathcal O n cdot log n nbsp im Durchschnitt und im Worst Case und erzielt bei vielen nahezu sortierten Eingaben eine nahezu lineare Leistung Es werden jedoch nicht alle nahezu sortierten Sequenzen optimal verarbeitet 6 Ternare Heaps Bearbeiten Eine andere Optimierung verwendet statt binaren ternare Heaps Diese Heaps beruhen statt auf Binarbaumen auf Baumen bei denen jeder vollstandig besetzte Knoten 3 Kinder hat Damit kann die Zahl der Vergleichsoperationen bei einigen Tausend bis einigen Millionen Elementen um etwa 3 reduziert werden Ausserdem sinkt der sonstige Aufwand deutlich Insbesondere mussen durch den flacheren Heap knapp ein Drittel weniger Elemente beim Versickern Heapify verschoben werden In einem binaren Heap kann ein Element mit 2 n displaystyle 2 cdot n nbsp Vergleichen um n displaystyle n nbsp Ebenen abgesenkt werden und hat dabei durchschnittlich 3 2 2 n 1 displaystyle tfrac 3 2 cdot 2 n 1 nbsp Indizes ubersprungen In einem ternaren Heap kann ein Element mit 3 m displaystyle 3 cdot m nbsp Vergleichen um m displaystyle m nbsp Ebenen abgesenkt werden und hat dabei durchschnittlich 3 m 1 displaystyle 3 m 1 nbsp Indizes ubersprungen Wenn bei gleicher Reichweite der relative Aufwand x 3 m 2 n displaystyle x tfrac 3 cdot m 2 cdot n nbsp ist dann gilt 3 2 2 n 1 3 2 n x 3 1 displaystyle frac 3 2 cdot 2 n 1 3 frac 2 cdot n cdot x 3 1 nbsp also x 3 2 n log 3 3 2 2 n 1 2 n 3 2 log 3 2 0 946 displaystyle x frac 3 2 cdot n cdot log 3 left frac 3 2 cdot 2 n frac 1 2 right n to infty frac 3 2 cdot log 3 2 approx 0 946 nbsp Bei n 18 displaystyle n 18 nbsp realistisch bei knapp 1 Million Elementen ergibt sich 0 977 Die 1 wird oberhalb von n 10 displaystyle n 10 nbsp unterschritten In der Praxis ist die Ersparnis etwas grosser u a deswegen weil ternare Baume mehr Blatter haben und deshalb beim Aufbau des Heaps weniger Elemente versickert werden mussen Insgesamt kann die Sortierung mit ternaren Heaps bei grossen Feldern mehrere Millionen Elemente und einfacher Vergleichsoperation 20 bis 30 Zeit einsparen Bei kleinen Feldern bis etwa tausend Elemente lohnen sich ternare Heaps nicht oder sind sogar langsamer n are Heaps Bearbeiten Bei noch breiteren Baumen bzw flacheren Heaps steigt die Zahl der notigen Vergleichsoperationen wieder an Trotzdem konnen sie vorteilhaft sein weil der sonstige Aufwand vor allem der fur das Kopieren von Elementen weiter sinkt und geordneter auf die Elemente zugegriffen wird was die Effizienz von Caches erhohen kann Sofern bei grossen Feldern nur ein einfacher numerischer Vergleich durchzufuhren ist und Schreiboperationen relativ langsam sind konnen 8 oder mehr Kinder pro Knoten optimal sein Einfache Beispielsimplementierung mit Heaps beliebiger Aritat WIDTH mit WIDTH gt 2 in der Programmiersprache C static size t heapify int data size t n size t WIDTH size t root assert root lt n size t count 0 int val data root size t parent root size t child 0 assert parent WIDTH gt parent Overflow Test while child parent WIDTH 1 lt n erstes Kind Abbruch am Ende des Heaps size t w n child lt WIDTH n child WIDTH Anzahl der vorhandenen Geschwister count w size t max 0 for size t i 1 i lt w i grosstes Kind suchen if data child i gt data child max max i child max if data child lt val kein Kind mehr grosser als der break zu versickernde Wert data parent data child grosstes Kind nach oben rucken parent child in der Ebene darunter weitermachen data parent val gesiebten Wert eintragen return count size t nhsort int data size t n size t WIDTH assert WIDTH gt 1 if n lt 2 return 0 size t m n WIDTH 2 WIDTH erstes Blatt im Baum int count 0 Zahler fur Anzahl der Vergleiche assert m gt 0 for size t r m r gt 0 r Teil 1 Konstruktion des Heaps count heapify data n WIDTH r 1 for size t i n 1 i gt 0 i Teil 2 eigentliche Sortierung int tmp data 0 Spitze des Heaps hinter den Heap in data 0 data i data i tmp den sortierten Bereich verschieben count heapify data i WIDTH 0 return count Zu Vergleichszwecken gibt die Funktion die Anzahl der durchgefuhrten Vergleiche zuruck Siehe auch BearbeitenHybridsortLiteratur BearbeitenThomas H Cormen Charles E Leiserson Ronald L Rivest Clifford Stein Introduction to Algorithms 2 Auflage MIT Press Cambridge MA 2001 ISBN 0 262 03293 7 S 135 Donald E Knuth The Art of Computer Programming 2 Auflage Volume 3 Sorting and Searching Addison Wesley Reading MA 1997 ISBN 0 201 89685 0 S 145 englisch Robert W Floyd Algorithm 245 Treesort 3 In Communications of the ACM Band 7 Nr 12 Dezember 1964 S 701 J W J Williams Algorithm 232 Heapsort In Communications of the ACM Band 7 Nr 6 Juni 1964 S 347 348 Robert W Floyd Algorithm 113 Treesort In Communications of the ACM Band 5 Nr 8 August 1962 S 434 Weblinks Bearbeiten nbsp Wikibooks Heapsort Implementierungen in der Algorithmensammlung nbsp Commons Heap sort Sammlung von Bildern Videos und Audiodateien Video zur Visualisierung von Heap Sort auf vimeo com Hans Werner Lang Sortierverfahren Heapsort auf der Seite der Hochschule Flensburg 1997 1 2 Vorlage Toter Link programmierung saschaseidel de VisuSort Framework Seite nicht mehr abrufbar festgestellt im Oktober 2022 Suche in Webarchiven Visualisierung diverser Sortieralgorithmen Windows Heaptsort auf sortieralgorithmen de Heapsort in Python 3 Heap queue algorithm auf docs python orgEinzelnachweise Bearbeiten Russel Schaffer Robert Sedgewick The analysis of heapsort In Journal of Algorithms Volume 15 Issue 1 Juli 1993 S 76 100 ISSN 0196 6774 Bela Bollobas Trevor I Fenner Alan M Frieze On the best case of heapsort In Journal of Algorithms Volume 20 Issue 2 Marz 1996 S 205 217 ISSN 0196 6774 Gu Xunrang Zhu Yuzhang Optimal heapsort algorithm Paul Hsieh Sorting revisited azillionmonkeys com 2004 abgerufen am 26 April 2010 David MacKay Heapsort Quicksort and Entropy aims ac za mackay 1 Dezember 2005 archiviert vom Original am 7 Juni 2007 abgerufen am 26 April 2010 Stefan Hertel Smoothsort s behavior on presorted sequences In Information Processing Letters 16 Jahrgang Nr 4 13 Mai 1983 S 165 170 doi 10 1016 0020 0190 83 90116 3 uni saarland de PDF Abgerufen von https de wikipedia org w index php title Heapsort amp oldid 234821962