So, guten Morgen. Wir werden uns heute mit den Splaytrees beschäftigen und die Hintergrund dieser Bäume ist,
dass wir versuchen wollen, einen Baum zu konstruieren,
also eine Datenstruktur zu bauen, die die klassischen Wörterbuchoperationen realisiert,
also einfügen und löschen von Objekten und diese dann durch Suchoperationen wiederzufinden unter der Annahme,
dass die Objekte einer Ordnung folgen.
Das ist immer die Grundvoraussetzung dafür, dass wir solche immer einsetzen können.
Und zwar wollen wir diesen Baum so konstruieren,
dass er selbst organisierend ist und der Annahme folgt,
dass wenn sie ein Objekt angefragt haben, wahrscheinlich ist,
dass sie das in Zukunft nochmal anfragen werden. Das ist ein Szenario,
was eben sehr häufig in der Anwendung vorkommt,
wenn sie sich vorstellen,
die haben halt irgendwie Kataloge mit Objekten und dann gibt es halt Objekte,
die werden halt, sind halt sehr stark frequentiert in irgendeinem Bücherkatalog,
gibt es einfach die Bestseller,
die werden immer angefragt und andere,
die werden selten angefragt und in einem Suchbaum ist es ja so,
je näher sie an der Wurzel stehen,
umso kürzer ist natürlich
die reale Suchzeit
Diese Eigenschaft wollte man oder will man ausnutzen und quasi einen Suchbaum jetzt nicht beim Einfügen und Löschen balancieren,
so wie wir das kennen, von AVL-Bäumen oder Rot-Schwarzräumen,
sondern bei jeder Suchanfrage, wenn man den Baum etwas umarrangieren,
um dafür zu sorgen,
dass die angefragten Objekte näher an die Wurzel kommen.
Das ist quasi das Ziel und ja, das ist,
das ist eines der Hauptziele. Was noch hinzukommt, ist,
wir sehen, dass bei den Verfahren, die wir haben,
für balancierte Suchbäume wie immer Etwas zusätzliche Informationen speichern müssen.
Das ist jetzt im heutigen Zeitalter eine eher esoterische Frage,
weil bei Rot-Schwarz-Bäumen geht es ja gerade mal um ein einziges Bit.
Ja, wir müssen an einem Rot-Schwarz-Warm, um die Balance zu realisieren,
ein Bit speichern, nämlich entweder rot oder schwarz, ja.
Beim AVL-Baum brauchen wir zwei Bitter, haben wir einen Balancewert,
der entweder minus 1-0 oder plus 1 ist.
Das ist natürlich minimaler Informationsgehalt im Verhältnis zu den Objekten,
die dort wahrscheinlich gespeichert werden und spielt also insofern keine große Rolle.
Aber es ist erstmal so,
und da stellt sich natürlich auch die theoretische Frage,
ob wir, um Balance zu erreichen,
immer mehr mehr Informationen speichern müssen, als die reinen Objekte selber.
Ja, das sind die beiden Punkte. Ach so,
es gibt da noch einen dritten. Ich weiß nicht,
wer von Ihnen sich schon mal den Spaß gemacht hat,
so einen balancierten Suchbaum selber zu programmieren.
Also heutzutage ist es ja glücklicherweise nicht mehr so nötig.
Also dann nehmen Sie in der Bibliothek aus dem Internet,
da sind balancierte Suchbäume wahrscheinlich als Datenstrukturen verfügbar.
Wenn man das mal macht und mal selber sich hinsetzt,
ein AVL oder ein Rot-Schwarzbaum zu programmieren,
mit Einführung und Löschoperationen, dann sieht man mal,
wie komplex das wirklich ist von der Softwareentwicklung.
Also diese ganzen Sonderfälle, die man programmieren muss,
um das zu machen, das ist schon wirklich sehr aufwendig.
Ja, die drei Punkte wollte man angehen,
als man die selbstorganisierten Bäume entwickelt hat.
Die heißen übrigens manchmal auch selbst anordnend oder Self-Adjusting im Englischen dann.
Also man wollte ohne zusätzlichen Speicher auskommen. Man wollte eine
möglichst einfache Implementierung der Wörterbuchoperation einfügen, löschen und suchen.
Das hatte unter anderem den Hintergrund, dass man zu der Zeit,
die sind in den 80er Jahren entstanden,
wollte man diese Suchanfragen möglichst auch direkt in Hardware bauen.
Ja, sie wollten direkt Komponenten bauen, die das optimal schon unterstützen.
Und wenn sie da so eine super komplizierten Balancierungsalgorithmus haben,
dann geht das natürlich nicht so einfach.
So, und dann eben die Umorganisation bei Anfrage eines Objektes.
So, und im Idealfall hätten wir jetzt gerne natürlich immer noch
unsere Worst-Case-Laufzeit bei N-Wörterbuch-Operationen von Log-in. Ja,
also das ist ja die Zeit, die wir wissen,
die notwendig ist und die auch quasi eine untere Schranke darstellt,
die wir ableiten können, aussortieren, dass wir also bei N-Operationen,
also mindestens N-Log-in brauchen, um die ganze Sequenz abzuarbeiten,
weil wir damit eben sortieren können,
ja,
mit einem Wörterbuch
Okay, gut. Also das war quasi das Ziel und
dann sind eine Reihe von solchen selbstorganisierenden Bäumen entstanden.
Wir stehen so ein paar Namen, Optimum, Search,
Tree, Bias, Search, Trees, Finger,
Search, Trees und eben diese Splaytries.
Und ich habe mir die Splaytrees rausgesucht,
um die hinten hier als ein Beispiel mal zu zeigen.
Die Idee von den Splaytrees ist, wir verwenden also Rotation,
um ein Objekt, was wir angefragt haben,
im Baum zur Wurzel zu schieben.
Dadurch rutscht der Knoten nach oben und andere Knoten rutschen irgendwie
ein bisschen weiter runter
Und die Idee, wie gesagt, ist,
wenn wir es gerade angefragt haben,
ist die Wahrscheinlichkeit vielleicht höher, dass wir es wieder anfragen.
Und selbst wenn wir es ein bisschen später anfragen,
mit jeder Anfrage rutscht es zwar wieder ein bisschen weiter runter im Baum,
aber es ist tendenziell näher an der Wurzel.
Das ist das Ziel. Wir haben eigentlich nur eine Operation,
mit der wir alles machen. Das ist eine sogenannte Splay-Operation.
Diese Splay-Operation wird eben das Objekt suchen und beim Suchprozess an die Wurzel verschieben.
Die werde ich Ihnen gleich vorstellen. Die Play-Operation arbeitet so,
dass manchmal macht man ja eine Anfrage und das Objekt
ist gar nicht in dem Baum drin.
Wenn das vorkommt, dann wird die automatisch immer den
symmetrischen Vorgänger nehmen und den dafür in die Wurzel schieben
Okay. Ja, das ist noch,
das habe ich letztes Mal schon gezeigt, das Bild,
das finde ich wirklich toll,
das ist auf der Webpage von dem Robert Tarjan,
der das entwickelt hat, der Robert Tarjan,
den haben wir schon mehrfach hier gesehen, er hat viele,
viele spannende Sachen in der Algorithmik entwickelt,
aber zu dem Mal ist die im Schrank war so wichtig oder es war das eine,
wo er so ein tolles Bild für hatte,
dass das auf seiner Homepage gelandet ist,
das ist auch heute noch so.
Ja, könnt ihr nochmal gucken, habe ich letztens nochmal nachgeguckt,
dass es nach wie vor auf seiner Homepage.
Ja, okay, so was ist die Idee? Also die Idee ist jetzt die Folgende,
wir haben also einen Suchbaum, der sieht irgendwie so aus,
im folgenden sind sie die Bäume immer so, die haben halt,
meine Knoten sind ja die Runden, und dann,
wenn die so Dreiecke sehen, sind das immer Teilbäume, die noch beliebig weiter irgendwie gehen.
Und wenn sie sich vorstellen, sie haben zum Beispiel einen solchen Baum,
der ist jetzt nicht besonders balanciert, naja, weiß man nicht,
man weiß nicht, wie groß diese Teilbäume hier sind.
Und wir fragen jetzt ein Objekt an.
Wir könnten zum Beispiel das Objekt A anfragen.
Dann können wir ausgehend von A quasi Rotationen ausführen,
die dazu führen, dass sich A langsam zur Wurzel bewegt.
Wenn wir nämlich um den Knoten B rotieren,
dann würde das A hochrutschen und das B runter
Der nächste Warm, den wir dann hätten,
der sehe eben so aus, wir haben hier das A,
da ist D und dann C, ja,
und nach dieser ersten Rotation hätten wir denn hier A und B,
ja, und dann hängen natürlich die Teilbäume hier dran,
die male ich mal jetzt nicht alle an die Tafel.
So, und jetzt sehen wir die Entfernung von A zur Wurzel hat sich verkürzt,
wir hatten hier ein, zwei, drei,
vier Kanten und jetzt haben wir ja noch drei Kanten, ja.
Dementsprechend können wir jetzt weitermachen,
wir können als nächstes um das C hier rotieren und dann
kriegen wir irgendwie e.de und das A rutscht hier hoch,
da wäre dann das C und hier wäre das B,
es wäre die nächste Rotation und jetzt ist das A noch genau.
Zwei Knoten oder zwei Kanten von der Wurzel entfernt,
die nächste Rotation wäre jetzt hier an dem D und dann hätten wir oben das E.
Hier kommt es falsch, geht es schon los.
Hier ist das D, hier ist das E und hier würde dann das A hochrutschen.
Hier ist das C und da ist das W. Ich hoffe,
dass es jetzt stimmt. Also wir haben hier gedreht und
mit der nächsten Rotation würde das A dann in die Wurzel gehen.
A, gibt dann hier hoch, die E,
hier war das B. Ja, und hier wäre das C. Ja?
Stimmt das? Das B? Das Kleidungstef D,
dann kann es jetzt nicht am rechten Teilbaum hängen.
Ja, genau, habe ich ihn falsch gedreht.
Also, der war noch richtig, ne? So,
dann haben wir an A gedreht, dann geht das B
da rüber, der war auch noch richtig.
Dann haben wir an dem gedreht, da geht das B
mit linker Viso B ist doch, wie ist kleiner als...
Wie kann man auch wieder weitermachen? Ach so,
der bleibt dann eher, ja stimmt, deblattiert, ne?
So, und jetzt, oh nein, oh nein,
wenn man sowas aus dem Kopf macht, das geht immer schief.
Okay, so, nochmal einmal drehen, also das A geht dann hoch,
D geht nach rechts, E geht nach unten,
das C bleibt linkes Kind und das B,
ja das passt doch jetzt,
Sind das jetzt? Ach, Glück gehabt. Okay,
gut. Okay, also wir können, das heißt,
wir können mit Rotationsoperationen den Knoten zur Wurzel bringen.
So, okay, wie machen wir das?
Wir definieren einfach eine Funktion, die heißt Rotate Up.
Die macht entweder eine links oder eine Rechtsrotation, weil das,
was wir gucken müssen, ist immer, ob den Knoten,
den wir bewegen wollen, ob der linker oder rechter,
linkes oder rechtes Kind ist, ja.
Dementsprechend müssen wir an dem darüber liegenden Knoten
entweder eine links oder eine Rechtsrotation ausführen.
Und das macht einfach diese Funktion Rotate Up.
Die guckt einfach, ist es ein linkes oder ein
rechtes Kind
Und dementsprechend führen wir dann die entsprechende Rotationsoperation an dem Elternknoten sozusagen durch.
Und die Funktion ist natürlich jetzt für die Wurzel irgendwie nicht definiert.
Da kann ich das natürlich nicht mehr machen. Okay,
so, und das, was ich hier gerade versucht habe in Schritten,
ihnen vorzumachen, ist das Move to Root.
Das ist quasi eine wiederholte Anwendung dieser Roadhate-Up-Funktion, wo wir sagen, okay,
wir haben einen Knoten X oder ein Objekt X, das fragen wir an.
Da machen wir eine Suche in dem Baum,
also eine klassische binäre Suche in dem in den Baum,
die bei der Wurzel anfängt und nach rechts und links verzweigt,
je nachdem, ob das Objekt in dem Knoten kleiner oder größer ist.
Wir kommen bis zu dem Knoten runter. Dann sind wir
auf dem Knoten und jetzt kommt diese Wild-Schleife hier,
die von diesem Knoten wieder hochgeht zur Wurzel und immer das Rolltate-Up ausführt,
so lange, bis wir quasi den Knoten hochgeschoben haben.
Und das führt uns zu diesem Baum. Sie haben ja
gar nicht gesagt, dass der anders aussieht als der,
den ich angemalt habe.
Der Spruch braucht sich aber auch
anders ausreichen
ADC, ABA, okay. Gut, egal. Gut,
also, Sie wissen jedenfalls, wie es funktioniert. So,
das ist die Strategie und beachten Sie, wir schauen uns
bei dieser ganzen Operation die Balance eigentlich nicht mehr an.
Ja, also es ist nicht so,
wie bei dem Rot-Schwarz-Bäumen, dass wir quasi vorher schauen,
ob, also dass wir irgendwie ein Gefühl dafür haben,
wie balanciert der Baum ist und dementsprechend die Rotation so rum oder so rum ausführen,
um dann eine bessere Balance hinzukriegen.
Das passiert hier nicht mehr. Ja,
die Rotationen haben nur das Ziel, den einen Knoten
bis zur Wurzel
zu transportieren
Okay, so, das hat man dann analysiert,
diese Move-to-Roo-Touristik und die fand man irgendwie auch schön.
Die hat halt diesen, die erfüllt halt diese Zwecke.
Erstens, ja, wir brauchen keinen zusätzlichen Speicher.
Wir merken uns ja keinen Rot-Schwarzwert oder irgendwas. Ja,
und zweitens, wir schieben das Objekt in die Wurzel.
Wir haben also eine verkürzte Zugriffszeit, wenn wir das Objekt nochmal anfragen.
Aber bezüglich der Laufzeit konnte man dann zeigen,
dass diese Heuristik einfach nicht zu diesem optimalen Szenario führt.
Die asymptotische Worst-Case-Laufzeit der Funktion ist O von N. Klar,
ich kann immer so einen ungünstigen Fall konstruieren,
wo ich dann so einen entarteten Baum habe
Und dann habe ich einfach den Fall, wo ich fast
eine lineare Liste habe und dann quasi entsprechend so lange brauche,
um da durchzugehen. Und es ist allerdings schon so,
dass die mittlere Zugriffszeit auch bei Login liegt.
Das ist auch nicht so erstaunlich, weil man zeigen kann,
dass ein zufälliger binärer Baum auch eine lugorithmische Tiefe schon hat.
Also wenn wir einfach mal summieren über alle möglichen binären Bäume
mit einen Knoten, dann kann man sehen,
dass die im Mittel halt schon lugorithmische Tiefe haben.
Deswegen kriegt man hier auch im mittleren Fall schon Login.
Aber man kann Zugriffssequenzen erzeugen, die im Worst Case
auch im amortisierten Fall Laufzeit-O von Täter von N haben.
Also pro Operation Täter von N. Also die kann man produzieren.
Das heißt, im Worst Case gibt es immer Sequenzen,
die zu dem schlechten linearen Verhalten der Suchoperationen führen.
Das werde ich jetzt nicht weiter beweisen oder so,
aber das ist quasi erstmal der Sachstand mit dem Move to Root.
So, das haben sich Slater und Targern angeschaut und haben sich
dann was überlegt und sie haben faszinierenderweise nur ein Detail geändert,
wie wir jetzt gleich sehen werden.
Also sie machen auch einen Move to root. Sie werden
also auch votieren und den Knoten so langsam nach oben bewegen.
Und was sie aber anders machen, ist,
sie schauen sich nicht immer nur von einem Knoten den direkten Vorgänger an,
sondern sie schauen sich zwei Kanten an.
Also die zum Vorgänger und zum Vorvorgänger. Und dann unterscheiden sie drei Fälle. Also der erste Fall,
wie heißt es, den folgenden SIG-Fall,
das steht für zig und zack, also zick, zack,
Zick-Fall, das ist der SIG-Fall, das ist der Fall,
wenn ich nur noch einem Knoten von der Wurzel entfernt bin,
so wie hier, Dann habe ich ja keinen Vorvorgänger mehr, dann kann ich mir den auch nicht angucken.
Und in dem Fall mache ich eigentlich so das Gleiche wie bei der Move-to-Root-Teuristik.
Ich werde einfach quasi diese eine Rotation machen.
Weil hier habe ich eh keinen Vorvorgänger mehr.
Diese Sieg-Operations-Kritt immer nur im letzten Schritt auf.
Wenn ich also einen Knoten von der Wurzel entfernt bin.
So, ansonsten kann ich mir immer zwei angucken.
Also ich kann hier ein, zwei operativ weit gucken.
Und dann unterscheide ich den sogenannten Sixick-Fall vom Sixick-Sec-Fall.
Das hier ist ein Sixack-Fall. Das heißt,
wir gehen einmal nach links oder ein, danach einmal nach rechts.
Wir können auch einmal nach rechts gehen, einmal nach links
Und wenn die Richtung der Kanten unterschiedlich ist, dann haben wir immer ein Six-Seck.
Und wenn die Richtung der Kanten gleich ist, wie zum Beispiel hier,
dann würden wir nach rechts und nach rechts,
also zweimal linkes Kind, dann haben wir den Six-Seck-Fall.
Das sind die beiden Fälle, die wir unterscheiden.
Und dann spielt rechts und links spielt keine Rolle.
Es geht nur darum, zweimal in die gleiche Richtung oder
in unterschiedliche Richtungen. Die beiden Fälle unterscheiden wir. So,
und dann passiert Folgendes im Fall im Fall Six-Sick.
Also wenn wir zweimal die gleiche Richtung haben,
so wie hier, da machen wir Jetzt kommt das Detail,
was eigentlich anders ist. Da machen wir Folgendes,
wir rotieren erst die Kante zwischen den Elternknoten und den Großelternknoten
und danach erst die Kante zwischen dem Objekt selber und dem Elternknoten.
Wir vertauschen die Rotation dieser beiden Kanten und machen das in
der anderen Reihenfolge. Und das ist der einzige Unterschied,
weil im Six-Sec-Fall rotieren wir genau, wie vorher auch,
also immer, wir nehmen den Vorgänger und den Knoten N. Ja,
und das machen wir zweimal hintereinander.
Das ist eigentlich nichts weiter wie das, was Move to
Root auch macht. Also der Fall ist genau gleich,
der Six-Fall auch nur in dem Fall,
wo wir zweimal in die gleiche Richtung gehen, da machen wir etwas anderes,
rotieren erst die Vorgängerkante hier zwischen Eltern und Ostelterknoten und dann die eigentliche Kante hier.
Okay, es ist, also allein die Vorstellung,
dass diese eine kleine Änderung tatsächlich den Unterschied machen soll,
ist schon relativ faszinierend,
aber es ist in der Tat so und wir werden jetzt als nächstes
erstmal die Splay-Operationen anschauen und danach werden wir uns die Analyse anschauen,
aus der man dann ableiten kann,
dass das tatsächlich so ist
Okay, wie setzen wir das Ganze um?
Wir brauchen eine Funktion, die uns immer sagt,
ob unser Kind jetzt ein linkes oder ein rechtes Kind ist.
Das könnte man natürlich auch direkt in dem Pseudo-Code einbauen.
Es gibt hier so eine Hilfsfunktion, da kann man das
ein bisschen leichter lesen. Die heißt Child Deal oder Child Direction.
Und die gibt einfach Left oder Ride zurück, je nachdem,
ob der Knoten N ein linkes oder ein rechtes Kind ist.
Damit können wir ganz leicht dran gucken,
ob wir quasi den Six-Sack oder den Six-Sick-Fall haben.
Okay, so, jetzt kommt die Splay-Operation selber.
Die ist ziemlich kompakt und kurz. Wir machen also
unsere Baumsucher,
wir suchen das Objekt
Achten Sie, beachten Sie, dass das die modifizierte Variante ist?
Das heißt, wenn das Objekt nicht gespeichert ist,
gibt diese Funktion den symmetrischen Vorgänger zurück.
Das ist die eine Modifikation, die da drin ist.
Da kommt dann nicht irgendwie null oder false oder so,
sondern dann kommt der symmetrische Vorgänger.
Okay, so, jetzt kommt die Wildschleife hier.
Solange der Knoten N, den wir jetzt gefunden haben,
noch nicht die Wurzel ist, machen wir folgendes.
Wir gucken mal, ob der Parent-Knoten die Wurzel ist.
Das heißt, wir sind noch einen Knoten hier entfernt von
der Wurzel und dann wissen wir, wir haben diesen SIG-Fall.
Das heißt, wir machen eine Roadtate-Up-Funktion Knoten,
der wandert dann nach oben und in dem Augenblick haben wir
dann unser Ziel erreicht, sind dann also fertig.
Das ist immer die letzte mögliche Iteration. Also wenn das eintritt hier,
dann haben wir danach die Wurzel erreicht und dann wird diese Wildschleife auch terminieren.
Anderenfalls haben wir noch mindestens zwei Vorgänge und wir müssen nur die beiden Fälle unterscheiden. Und wenn wir in beiden Fällen,
also an dem Knoten N und an dem Vorgänger von N,
dem Elternknoten hier, die gleiche Richtung haben,
also beides links oder beides rechts,
dann haben wir den 6-6 Fell und dann rotieren wir quasi an dem Parent-Knoten,
Und wenn das nicht der Fall ist,
dann haben wir den normalen 66-Fall und dann rotieren wir an dem Knoten-N selber.
Und danach rotieren wir den Knoten-N nochmal. Hier ist quasi
der eine Unterschied, dass diese IF-Bedingung mit der Fallunterscheidung,
welchen Knoten wir drehen. Das ist der eine Unterschied.
Zwischen der Move to Root-Teuristik und der Splay-Operation. So,
das ist eigentlich schon alles. Also das ist ein,
wir werden hier heute ein Beispiel sehen oder das Paradebeispiel in dieser Vorlesung
von einem sehr einfachen Algorithmus mit einer sehr schwierigen Analyse.
Das ist erstmal leicht zu verstehen. Und es ist auch
leicht zu implementieren. Also das könnten Sie wahrscheinlich mit ein
bisschen Programmiererfahrung, haben Sie das in zwei Stunden lauffähig?
Wir müssen noch überlegen, wie kriegen wir diese Play-Operation
jetzt eingebettet, sodass wir unsere Wörterbuchfunktionen haben.
Wir müssen ja noch einfügen und löschen können.
Das ist das Nächste, was wir uns überlegen.
Aber erst mal, ach, ich habe noch ein Beispiel natürlich.
Und dann überlegen wir uns das, okay, hier ist nochmal ein Beispiel.
Hier sehen Sie auch immer den Unterschied zwischen Move to Root.
Hier ist die SIG-Operation, wir haben also das X,
da würden wir das machen,
Einkommen von der Wurzel
Entfernt und bei der SIG-Operation und Move to Root kommt das Gleiche raus.
X wird nach rechts rüber gedreht, der Teilbaum, JB,
der wird linkes Kind von Y und das ist alles.
Dann haben wir die SIX-SEC-Operation, X ist hier. Wir sehen,
X ist ein rechtes Kind und Y ist ein linkes Kind.
Es ist ein SIX-SEC und hier passiert das Gleiche wie bei Move to Root.
Wir machen eine Rotation nach links hier unten. Dann haben wir hier das X,
das Y wäre Kind davon und dann machen wir eine Rotation
nach rechts und dann ist X in der Wurzel.
Y ist links, Z ist rechts. Okay,
so, der eine Fall, achso,
Was ich ihm mal hier aufgeschrieben habe, ist,
nur mal so Interesse heilbar, dass man das mal sieht,
was eigentlich mit den Niveaus passiert.
Also wie verändern sich eigentlich die Entfernungen der Knoten zur Wurzel
, wenn man das macht. Und da sieht man,
der Knoten X hier, der rutscht einen Knoten,
eine Kante näher an die Wurzel ran.
Der geht hier eine Etage hoch. Der ganze Teilbaum A auch,
der geht auch eine Kante hoch, deswegen steht hier eine Minus 1.
Der Teilbaum B, alle Knoten hier,
die verändern sich nicht,
die bleiben auf dem gleichen Niveau
Und der Knoten der Y, der geht jetzt eine Etage
runter, der entfernt sich eins von der Wurzel.
Der hat also plus eins und das C hier hat auch plus eins.
Also dieser ganze Tybon geht auch eins runter. Wenn man mal so schaut,
wir wissen jetzt nicht genau,
wie viele Knoten in A oder C sind,
das haben wir jetzt nicht definiert, es sind irgendwelche Teilbäume,
aber wenn man jetzt noch davon ausgeht,
die werden so ungefähr gleich groß, dann hat sich nicht viel verändert.
Also es ist, es ist irgendwie balanciert in dem Sinne,
dass ungefähr genauso viel hochgerutscht ist wie runter.
Es ist, muss ja einfach irgendwie so sein,
weil der Binärbaum hat ja
nur zwei Kinderproknoten
Hier im 6-6-Fall kann man sich das auch angucken,
was passiert, also der Knoten X,
der wandert jetzt natürlich zwei Etagen hoch,
also zwei kannten näher an die Wurzel,
der hat jetzt eine minus zwei.
Y bleibt da, wo er ist, der hat null.
Z wandert eins runter, der hat dann plus eins.
Und hier haben wir jetzt den Teilbaum A, der bleibt auf der Höhe,
wo er ist. Teilbaum D geht eine Ebene runter,
Taiwan B und C gehen aber beide eine Ebene hoch.
Auch hier kann man nicht genau sagen,
was das bedeutet, weil wir wissen nicht,
wie groß die Teilbäume unter A, B, C,
D sind und wie tief die vor allen Dingen sind.
Deswegen wissen wir nicht genau, ob das ein Vorteil ist,
aber wir sehen zumindest, wir haben zwei Teilbäume von den Vieren,
die tatsächlich eine Ebene hochrutschen und einen,
der eine Ebene runterrutscht.
Sieht erst mal tendenziell nicht schlecht aus, das so zu machen.
So, wir gucken uns jetzt noch den Sixig-Fall an.
Also wir haben hier die vier Teilbäume. Hier haben wir
jetzt die Situation. X ist jeweils linkes Kind von Y
und Y, das linkes Kind von Z.
Das ist der Sixig-Fall. Wir würden also, ja,
wie machen wir hier unten erst mal Move to Loot.
Wir würden XY drehen, X geht hoch, Y geht runter.
Und dann würden wir XZ drehen,
dann geht X hier hoch,
Z geht da runter und wir hätten diese Konstellation danach
Das ist quasi mit Move to Root. Bei Sixick drehen wir
erst an der Kanze YZ. Das heißt Y geht hoch
und Z wird rechtes Kind von Y. Und dann drehen wir
die Kante XY und als Resultat kriegen wir das hier.
Das heißt XWit-Wurzel Y ist rechtes Kind. Z ist wiederum
rechtes Kind. Und wir haben hier die entsprechenden Kinder.
Vor allem C und die Teilbäume C und D. Okay.
Tja, also es ist nicht so klar,
was das jetzt im Verhältnis zu dem hier bringen soll.
Wir können auch die Höhen angucken
Also wenn wir so einen Sixig-File machen,
dann wandert das x, zwei Etagen hoch.
Das Y bleibt da, wo es ist.
Set geht zwei runter. Das ist also irgendwie, naja,
hat es gleich geblieben, wenn man so die Höhen mal akkumuliert.
Wenn man die Teilbäume anguckt, auch, also B,
G, zwei Etagen hoch, B auch,
C geht aber eine Etage runter und D auch.
Also die verlängern ihrem Pfad zu Wurzel um zwei Einheiten.
So, und bei Move to Root, ja,
da haben wir hier der Knoten nix.
Es gibt natürlich auch zwei Ebenen hoch,
der Teilbaum A auch.
Das ist genauso wie hier
Z und Y gehen jeweils eine Etage runter. Hier ging Z2 und Y
gar nicht. Und bei den Teilbäumen ist es hier,
haben wir zwei Teilbäume, die sind eine Ebene runtergegangen und der B verändert sich gar nicht.
Also es sieht eher so aus, man weiß,
wie gesagt, man kann das jetzt nicht interpretieren,
weil man nicht weiß, wie groß die Teilbäume ist,
aber man sieht definitiv jetzt nicht ein klares Signal,
wo man sagen würde, ja,
das ist natürlich irgendwie geschickter oder so.
Das kann man in diesem Augenblick noch nicht genau sagen. Okay,
also die Veränderung der Höhen gibt es zumindest lokal gesehen,
keinen Aufschluss darüber, dass dieses Play-Apparation irgendwie günstig ist.
Das werden wir erst in der Analyse sehen
So, hier ist noch ein anderes Beispiel.
Es ist aus dem Display-Geschichte, kommt nicht im Kormen vor.
Das Beispiel ist aus dem Ottmann. Hier ist nochmal ein
etwas größerer Baum. Ja, und wann macht ihr die
Splay-Operation für den Knoten 11? Und dann sieht man,
11 ist hier, linkes Kind und nochmal linkes,
rechtes Kind und dann nochmal rechts des Kindes, der Sixig-Fall.
Wir würden also erst 8, 5 drehen und dann 11,
8, dadurch ist elf an dieser Position und 8 und 5 sind jeweils links davon.
Ja, wir sehen die Situation,
dass wir diesen Sixig-Fall rüber drin und dann nachher wieder so einen Sixig-Sick-Fall kriegen würden,
wenn wir jetzt fünf anfragen würden,
hätten wir das wieder so
Okay, und dann sind wir schon nur noch
ein Punkt oder eine Kante von der Wurzel entfernt,
da machen wir auch eine SIG-Operation und dann wäre das elf über die Elf,
das Objekt, was wir angefragt haben hier in der Wurzel.
Okay, so, jetzt brauchen wir noch unsere drei Operationen, suchen, einfügen, löschen.
Suchen geht wie folgt, wir machen die Splay-Operation. Danach haben wir das Objekt in die Wurzel geschoben,
wir müssen also nur die Wurzel angucken und jetzt kann es sein,
dass das Objekt entweder in der Wurzel drinsteht,
wenn ja, dann war das Objekt enthalten,
wenn das Objekt nicht enthalten war,
steht der symmetrische Vorgänger in der Wurzel,
das wäre dann ungleich X und dann würden wir hier Nil zurückgeben und andeuten,
okay, das ist das Objekt nicht im Baum enthalten war.
Beachten Sie, dass wir trotzdem,
also auch bei einer Anfrage eines Objekts, was nicht vorkommt,
quasi den Baum in der Play-Operation umarrangiert haben.
Es ist also nicht so, als hätten wir gar nichts getan.
Es ist nur so, dass wir nachher Nil zurückgeben,
weil das Objekt nicht vorkommt.
So, jetzt brauchen wir eine Einfüge und eine Löschoperation und
hier schon mal der Pseudo-Code fürs Einfügen. Sie sehen,
dass es sehr, sehr einfach auch gehalten Vielleicht erinnert sich
der eine oder andere noch an eine Inside-Operation im Rot-Schwarzbau.
Ja, wie aufwendig das war. Also hier ist es
einfach eine Splay-Operation. Und danach wird es so lokal an
der Wurzel ein bisschen was verändert.
Und ich zeige Ihnen erstmal an einem Bild,
was verändert wird und dann können wir uns das hier nochmal anschauen.
Okay, also hier ist ein Splay-Inside. Was wir machen
ist, wir fragen den Key selber an.
Ja, also den, die wir einfügen wollen.
Wenn das Objekt schon im Baum drin ist,
können wir es nicht mehr einfügen.
Also wir gehen davon aus,
dass die Schlüssel eindeutig sind
Das heißt, dann brechen wir diese Suche ab.
Anderenfalls steht jetzt der symmetrische Vorgänger in diesem Wurzelknoten drin. Okay,
wenn dieser symmetrische Vorgänger größer ist, als der Schlüssel selber,
dann wissen wir, dass der linke Teilbaum leer sein muss.
Denn und das einzuzufügende Objekt wäre dann das Minimum.
Das ist der kleinste Knoten, den wir dann einfügen.
So, in dem Fall ist es relativ einfach.
Wir können dann sagen, okay, unser Knoten-Z,
der wird jetzt quasi eine neue Wurzel.
Ja, das ist der Knoten-Set. Und wir wissen,
alle Knoten, die im Warum vorkommen, weil der Schlüssel
an Z ist ja das Minimum, werden rechtes Kind.
Das heißt, wir bauen diesen Baum Z,
dann kommt das Y und hier kommt dann dieser Teilbaum runter.
Das ist also der erste Fall, der auftreten kann.
Der tritt immer nur dann ein, wenn wir das Minimum einfügen.
Also wenn wir Objekte einfügen, was das Minimum ist.
Symmetrisch haben wir natürlich den Maximumfall, den werden wir jetzt
nicht mal angucken, aber nee, stimmt gar nicht.
Entschuldigung, den gibt es natürlich nicht. So,
den gibt es nicht, weil wir immer nach dem symmetrischen Vorgänger gucken.
So, der andere Fall ist, der Schlüsselwert ist größer als der Wurzelschlüssel.
Dann haben wir, hier ist das Bild zum zweiten Fall,
Dann sieht die Situation wie folgt aus.
Wir können hier so einen Schnitt machen. Alles,
was auf der linken Seite ist, ist dir kleiner als
der Schlüssel, den wir einfügen.
Wir haben ja noch den symmetrischen Vorgänger gefragt. Alles,
was rechts von diesem Schnitt ist, ist größer als der
Schlüssel, den wir einfügen wollen.
Und auch das können wir relativ leicht konstruieren,
indem wir Z zu einer neuen Wurzel machen.
Y und der linke Teilbaum werden beides linke Teilbäume.
Und der rechte Teilbaum, das waren ja die Objekte,
die größer waren als der Schlüssel, den wir einfügen wollen,
der wird halt so recht erteilbar.
Das ist die Insert-Operation. Und wir sehen schon,
wir achten jetzt gar nicht so sehr darauf, dass der extrem balanciert ist.
Also wir sind gerade im Bereich der Wurzel,
sind ja hier quasi leere Teilbäume.
Aber auf der Art und Weise ersparen wir uns,
so ein kompliziertes Rearrangieren der Knoten in dieser Phase.
So, jetzt können wir nochmal in den Pseudo-Code reingucken.
Also den Anfang hatten wir schon, die Splay-Operation dreht den symmetrischen Vorgänger in die Wurzel.
Wenn da schon der Key ist, können wir aufhören.
Anderenfalls gucken wir, ob Z.Key das Minimum im Baum ist,
weil wenn das noch kleiner ist als der symmetrische Vorgänger,
dann muss es das Minimum sein.
Dann können wir ein, können wir Z.left auf Nil setzen,
Z.Right wird die alte Wurzel von dem Knoten, von dem Baum.
Ja, und am Ende hier definieren wir dann die Wurzel als den Knoten-Set.
So, anderenfalls haben wir jetzt den Fall,
dass wir einen linken und einen rechten Teilbaum haben.
Wir setzen Z-Left auf die ehemalige Wurzel, Z-Right wird das rechte Kind der Wurzel.
Und das rechte Kind der alten Wurzel setzen wir auf Nil,
das löschen wir da oder verschieben es da weg.
Und am Ende wird Z zu neuen, wo es so.
Ja, also die Operationen machen genau
Musik Seit des Play-Operationen. Beim Insert rufen wir die Play-Operation
auf und danach müssen wir nur noch an der Wurzel
ein paar Zeiger ändern, um den Baum da umzuarrangieren.
Das geht alles in konstanter Zahl. Und bei der Suche
rufen wir auch nur die Splay-Operation auf und danach gucken wir
uns noch mal die Wurzel an.
Das geht auch in konstanter Zeit. Das heißt,
alle drei Operationen werden dominiert von der Laufzeit der Splay-Operation.
Wir müssen also nur wissen, wie lange dauert
die Splay-Operation?
Wir müssen amortisiert analysieren, weil wir können problemlos Situationen irgendwie konstruieren,
wo so eine Splay-Operation, die Laufzeit-Täter von N haben wird.
Das kriegt man irgendwie hin. Also das ist eine Einzeloperation
tatsächlich ungünstig ist, es immer zu machen. Aber wenn wir
eine Sequenz betrachten werden von End-Operationen, dann werden wir nachweisen können,
dass dann nicht immer dieser schlechteste Fall eintreten kann.
Genau wie am Anfang,
wo wir das erste Mal die amortisierte Analyse betrachtet haben,
dann können sie sich vielleicht nochmal erinnern an diesen Multipop,
da war es auch so,
da hatten wir ein Stack mit Push und Pop und dieser Multipop-Operation,
da gab es dann diese eine Operation,
die teuer ist,
ist Multipop
Ja, das war dann teuer, aber wir konnten zeigen,
dass die eben bei N-Ausführung der Operation eben nicht beliebig häufig vorkommen kann.
Hier ist es auch so, eine Einzeloperation kann teuer sein,
ja, aber amortisiert über N-Ausführungen werden wir eine gute Laufzeit erreichen.
Okay, also das ist das, was wir herausfinden müssen,
wie hoch ist die Worst-Case-Laufzeit der Splay-Operation über einer Sequenz von N-Operationen bei amortisierter Betrachtung,
wenn wir die amortisiert sehen als ganze Sequenz.
Okay, so, wir brauchen so ein paar hilfstechniken und
das ist hier eine eine ganz einfache, mathematische Umrechnung,
die ein ganz zentralen, eine ganz zentrale Rolle in der Analyse einnehmen wird.
Und zwar gilt Folgendes. Es ist ein ganz einfache mathematische Regel.
Wir haben A und B, die sind irgendwelche Zahlen größer, null. Und wenn wir,
und noch eine Zahl C,
und wenn A plus B, kleiner gleich zäh ist,
ja, also drei Zahlen A, B,
C. Und C ist eben größer oder gleich der Summe von A und B. Und A und B sind auch beide positiv.
Dann folgt daraus, dass der Logorithmus zur Wahl ist,
zwei von A plus der Logorithmus zur Basis 2 von B,
kleiner gleich zweimal Logorithmus zur Basis 2 von C
minus zwei ist
Wieso gilt das? Ist einfach so eine Rechenregel,
ja? Und ich könnte das jetzt dabei belassen,
aber damit sie mir das jetzt auch glauben,
dass das stimmt, das kann man ganz gleich zeigen.
Und zwar aus dieser Ungleichung, also wenn sie Wurzel-A-minus-Wurzelbeet
zum Quadrat rechnen, ist es ja eine positive Zahl.
So eine Quadratzahl ist ja positiv. Und aus dieser Ungleichung
folgt das Verhältnis von geometrisch zu arithmetischem Mittel,
das ist nämlich Wurzel-A-B, St. Geometrisches Mittel, kleinergleich,
A plus B halbe ist.
Ist übrigens auch ganz interessant zu wissen,
wenn sie es bis gerade noch nicht wussten,
biometrische Mittel ist immer kleiner als arithmetische Mittel
So, und wenn man das jetzt weiter umformt,
wenn man das A plus B durch C ersetzt,
steht da Wurzel-ABs, kleiner gleich C, halbe.
Jetzt können sie quadrieren, dann steht da A,
B, ist kleiner, gleich C, halbe zum Quadrat.
Jetzt können wir auf beiden Seiten logerithmieren,
dann haben wir Logorithmus zur Weise 2 von A, B,
ist kleiner, gleich zweimal Logorithmus zur Weise 2 von C, halbe.
Ja, also der Exponent geht ja nach den Logorithmenregeln dann als Faktor ein.
Und jetzt können wir nochmal die Logorithmenregeln anwenden und dann wird aus dem Logorithmus A,
B, Logorithmus A plus Logorithmus B, ja,
und aus dem Logorithmus von C halbe wird der Logorithmus von C minus 1,
ja, weil wir zu Basis 2 rechnen dann ist er ja noch der Faktor 2 davor.
Also zweimal Urhythmus, du weißt, 2 von C,
minus 2. Und diese minus 2 hier, die,
an die werden sie sich gleich noch erinnern müssen,
die brauchen wir in der Analyse.
Die wird das Entscheidende, das Entscheidende Zünglein in der Waage
sein, was dazu führt, dass die Analyse funktioniert.
Okay, so, was wir machen,
ist eine amortisierte Analyse mit der Potenzialmethode. Das heißt,
wir definieren eine Potenzialfunktion und werden dann zeigen,
dass entsprechend Potenzialdifferenz Minus oder plus, also die realen Laufzeitkosten plus Potenzialdifferenzen,
der dann die amortisierten Kosten und dass das dann quasi lugorithmisch sein wird.
Okay, wie sieht unsere Potenzialfunktion aus? Die Potenzialfunktion sieht
wie folgt aus. Wir fangen an und legen auf
jeden Knoten-Set in unserem Baum ein Gewicht drauf.
Dieses Gewicht werden wir im Folgenden gar nicht weiter betrachten.
Sie können jetzt im Ersten fürs allererste Mal so tun,
als wenn das eins wäre. Wichtig ist nur zu sehen,
wir haben da so eine Gewichtsfunktion und können die Gewichte beliebig
da drauflegen und wir werden im Folgenden sehen,
dass wir die Gewichte gar nicht so genau angucken müssen,
zumindest für den ersten Schritt der Analyse
Okay, also wir haben jetzt so ein Gewicht auf diesen Knoten drauf.
So, dann bestimmen wir die Größe eines Teilbaums. Wir sagen einfach,
wenn wir ein Knoten-Z haben, dann ist Tee von Z
der Teilbaum und wir addieren einfach die ganzen Gewichte.
Alles, was da drunter hängt von jedem Knoten,
dann nehmen wir das Gewicht, wir addieren das alles auf.
Und das ist diese Summe hier.
Das ist die Größe und das bezeichnen wir mal mit S.
Also S ist immer Size, das ist die Größe.
Als nächstes nehmen wir von diesem Wert den Logarithmus zur Basis 2.
Das bezeichnen wir als den Rang. Das ist R von
Z, das ist der Rang. Ja, ist einfach
nur der Zweier-Logarithmus von diesem Gewicht hier. So,
jetzt kommt die Potenzialfunktion und jetzt addieren wir nochmal über alle Knoten im Baum, diese Ränge.
Und das ist unsere Potenzialfunktion. Im Gegensatz zu den Analysen,
die wir schon gesehen haben, konnte,
da war es immer so,
dass man die Potenzialfunktion ziemlich gut motivieren konnte,
zu sagen, ja, die ist deswegen so,
weil wir sparen da die Zeit und sammeln das da auf und können das dann in der ungünstigen Operation verbrauchen.
Ich muss geschehen, dass ich hier nicht in der Lage bin,
in diese Funktion so zu motivieren. Das ist die Potenzialfunktion
und die funktioniert und ich kann Ihnen nicht genau sagen,
also ich Ich habe zumindest, also vielleicht einer von Ihnen,
das irgendwie im Kopf hat.
Also ich habe kein Bild im Kopf. Warum das sozusagen
gerade gut funktioniert? In den Rechnungen sieht man es dann.
Aber was man auf alle Fälle mal machen kann,
als ersten Schritt ist zu sagen, naja, wir kennen ja die Extremer.
Die Extremer, die wir haben, ist der entartete Baum.
Ja, also der entartete Baum wäre ja sowas hier.
Ja, sowas wie das. Also so eine lineare Liste.
Hier oben steht zum Beispiel das Minimum,
dann der zweitgrößte Knoten und so weiter.
Und dann geht es immer so weiter.
Das ist der entartete Baum. Und dann haben wir natürlich,
der andere Fall wäre jetzt der vollständig balancierte Bauen
Also das sind so zwei Extreme. Und das ist natürlich super,
weil wenn wir den balancierten Baum haben,
dann wissen wir schon, aha, der hat hier logorithmische Tiefe.
Ja, das ist, und dann werden die Anfrageoperationen,
die Splay-Operationen auch nur Lock-and-Site benötigen,
weil wir laufen ja dann hier runter und wieder hoch.
Super. In dem entarteten Fall haben wir natürlich hier
N-Tiefe oder Höhe von dem Blatt hier.
Ja, und da würde diese Splay-Operation lineare Zeit bringen.
Das ist also der ungünstigste Fall. Das ist der
ungünstigste Fall. Können wir also als nächstes mal ausrechnen,
was sagt denn unsere Potenzialfunktion zu diesen beiden Fällen
Ja, also was für ein Potenzial haben wir denn für diesen linearen Fall
und was für ein Potenzial haben wir für diesen optimalen Baum?
Weil die Idee wäre ja dann, hier haben wir ein,
hier haben wir ein relativ hohes Potenzial. Das bedeutet,
wenn wir hier eine Anfrage machen, eine Operation,
dann haben wir viel auf der Potenzialfunktion und können das benutzen,
abbauen, um quasi diese Anfrage zu stellen.
Während wir in diesem Fall wahrscheinlich ein relativ niedriges Potenzial haben,
weil da haben wir ja schon optimale Situationen und können
die Anfragen bestellen
Okay, was kommt bei einem linearen, bei der linearen Liste raus?
Bei dem entarteten Baum. Da können wir dann gucken,
okay, was ist denn das Potenzial? Wir wissen,
was ist die Summe über alle Knoten? Der Rang,
der Rang ist nichts weiter als der Logorithmus der Größe.
Und wenn ich jetzt mal für diese W-Funktion jetzt mal eins einsetze,
also W von IS1, für alle Knoten,
dann wäre das hier Log 2 von I.
Also ich muss dann hier nur die Höhe hier betrachten.
Und dann hätte ich hier die Summe von Igarch 1 bis End Logorithmus,
so war das 2 von I. Das kann ich
mit den Logorithmenregeln umformen,
Logorithmus zur Basis 2 von N-Fakultät
So, und jetzt kann ich das ganz grob abschätzen und sagen,
En-Fakultät, ja, das ist auf alle Fälle kleiner als N-Hoch-N.
Ja, und wenn ich das kleiner habe als N-Hoch-N,
dann wäre das auf alle Fälle ein O von N-Log-N. Ja?
Ich kann sogar zeigen, dass es im Tetter von N-Log-En
ist und hier steht auch, wie man das ausrechnen kann,
dass das in Tetter von N-Log-En ist.
Ja, die Oberschranke ist ja klar,
also weil N-Fakultät ist ja auf alle Fälle kleiner als N-Hoch-N.
Und der Logorithmus von Endow NSN Log-En.
Also wie kann man die untere Schranke sehen? Und wenn man
die untere Schranke anschauen will, dann muss man Folgendes machen.
Man muss nämlich die Produkte, man hat ja immer eine
kleine Zahl, die immer mit einer großen Zahl multipliziert.
Und wir können zeigen, dass ein Halb-End-Log-End kleiner gleich dieser Summe hier ist.
Also der Logerithmus zu Beiß 2 von Infakultät.
Und wie macht man das? Naja, also intuitiv gesprochen,
also End-Fakultät ist ja sowas, haben wir ja so eine Summe.
Ja, und das geht dann bis N. Ja,
und was wir zeigen wollen, ist quasi,
hier haben wir jetzt N-Faktoren,
Wenn wir das ändern können in sowas wie N,
mal N, mal N und so weiter.
Und wir haben hier nur noch eine halbe, viele Faktoren.
Dann hätten wir die Schranke erreicht. Und wir müssen zeigen,
dass dieses Produkt hier kleiner gleich Endfakultät ist.
Ja, wenn wir in halbe Mal das N hier multiplizieren.
So, und wie macht man das? Naja,
man muss sich einfach überlegen, man nimmt dir immer so
eine kleine Zahl und eine große Zahl.
Also hier N minus 1. Und die Kleine und die Große,
die nimmt man immer zusammen. Und dann zeigt man,
dass die Kleine und die Große,
dass das Produkt dann immer kleiner ist als
So, und das steht hier. Also,
was man zeigen kann, ist, dass Carplus 1 mal N-Sk,
das ist also die kleine Zahl, mal die Große,
ist immer größer gleich N,
das habe ich gerade kleiner gleich gesagt, größer gleich N.
Und sowas ist genau dann der Fall, das können Sie das ausklammern,
wenn Car mal N plus N minus Car,
minus Car-Qualat größer gleich N ist.
Und das ist genau dann der Fall, wenn K mal
N minus 1, minus K größer gleich null ist.
Und das ist natürlich der Fall, weil K und N
minus 1 minus K diese beiden Zahlen hier auf alle Fälle größer gleich null sind.
So, und dann kann man das einsetzen.
Und wenn Sie dann in halbe Mal N rechnen sie sagen,
dass N hier, das ist immer kleiner gleich,
diesem Produkt,
Carplus 1 mal N-K und dann haben sie hier das Produkt
von K gleich 0 bis N halbe minus 1. Und da kommt gerade jeder Faktor einmal vor und das ist eine Innenfakultät.
Und für N-Ungerade geht das auch, dann müssen sie dann eine,
so eine Wurzel N rausziehen, weil das ihr sonst,
damit sie wieder eine gerade Anzahl von Faktoren haben.
So, können Sie mal nachrichten. Das ist im Weiteren
auch nicht so wichtig, dass die nur dazu,
um zu zeigen, wie das Potenzial im Fall des entarteten
Baums ist
So, was ist jetzt beim vollständig Binärenbaum, wenn wir den Fall haben?
Da brauchen wir wieder so einen Tricks und mathematischen.
Und zwar, was wir brauchen, ist,
wir müssen eine geschlossene Vorbild für diese Summe haben.
Karl gleich 1 bis N kr mal 2
hoch K. Die kommt da vor. Ja, und das
ist die geschlossene Formel davon. Das ist N-minus 1,
mal 2 auch N plus 1 plus 2. Ja,
und wie kann man das sehen? Das können Sie jetzt
auch wieder ignorieren, was in dieser grauen Kiste steht.
Das ist nur um diese geschlossene Formel auszurechnen.
Die Art und Weise, wie man das macht,
ist, man differenziert die geometrische Reihe.
Man sagt dann Karl gleich 1 bis N
vom Karma X hoch
X-mal, K gleich 1 bis N, K mal x hoch,
K minus 1. Und das ist x-mal, und zwar die
Ableitung von diesem K, gleich 1 bis N x hoch
K. Weil wenn sie XOK ableisen, ist das ja Karma exokant bis 1. So,
und dann wissen sie, die geschlossene Formel für diese Summe,
das ist ja die geometrische Reihe, x auf N plus 1,
minus 1 durch x minus 1,
das können sie jetzt auch wieder differenzieren,
das ist jetzt schon ein bisschen schwieriger, auch mal so Quotientenregel und so.
Das vergisst man irgendwann nach dem Abitur wieder. Und dann haben sie diese Formel,
das können sie auflösen und dann kommen sie,
wenn sie dann für das X hier eine 2 Einsätzen,
genau zu der Formel da oben.
Ja, okay, können Sie jetzt einfach mal so hinnehmen,
dass das auf alle Fälle so ist.
Und jetzt können wir ausrechnen, was das Potenzial des Binärenbaums ist.
Ja, es ist Potenzial des Binärenbaums. Da überlegen wir uns,
aha, in so einem Binärenbaum, so einem vollständigen, binären Baum.
Ja, da ist die Situation ja wie folgt.
Da haben wir so Knoten auf verschiedenen Ebenen, ja,
und diese Knoten auf den verschiedenen Ebenen hier,
da wissen Sie immer, wie viel da drin sind.
Das sind dann immer zwei hoch i. Viele sind auf
einer speziellen Ebene
Dann können sie auch ausrechnen,
was das Potenzial eines solchen Knotens auf dieser Ebene ist.
Der hier, das ist die Wurzel,
der hat dann natürlich den Logarithmus von allen und die hier von denen,
die haben immer noch genau die Hälfte, minus eins und so weiter.
Und das können sie aufsummieren. Und dann kommen sie zu der Formel,
dann ist das Potenzial für den binären Baum, Summe,
Igleich 0 bis h minus eins.
Das sind dann diese Ebenen hier, wenn sie die runterbegehen.
Und dann haben sie zwei Hoch-I. Das ist die Anzahl
der Knoten, die sie auf der Ebene haben.
Das geht immer mit der Zweierpotenz hoch. Und dann haben
sie hier den entsprechenden Rang. Logarithmus zu Basis 2 von
der Größe und die Größe ist die Anzahl der Knoten,
die da drunter sind.
Das sind zwei Hoch-H-minus-I minus eins
Okay, da kann man dann die minus eins weglassen, dann steht da zwei hoch i malh-i,
ja, weil sie dann den Logorithmus ja hier,
die Exponentialfunktion gegeneinander aufheben können und dann können sie es ausrechnen und dann zerlegen sie hier die Summe,
dann haben sie Haar mal Idarch 0 bis H minus 1,
2 hoch i und hier haben sie dieses i mal 2 Ui,
das ist genau das, wo wir diesen Hilfssatz gleich für brauchen,
da können wir dann hier die exponentielle oder geometrische Reihe einsetzen und hier die Ableitung davon,
dann kriegen wir die geschlossene Form und dann fassen wir das nur noch zusammen und setzen für das Haar wieder den Logorithmus ein und dann steht da,
als Ergebnis für das Potenzial,
zweimal N-Logorithmus zur Basis 2 von N plus
1. Also hier haben wir ungefähr N-Log-N-Potenzial. Hier haben wir
lineares Potenzial, minus noch ein bisschen weniger.
Hier geht noch so ein Logorithmus ab. Und das ist
tatsächlich genauso, wie wir es jetzt erwartet hätten.
Also hier ist das Potenzial im Wesentlichen in den EA.
Hier ist es N-Log-N. Wir brauchen also hier ein höheres Potenzial in
dem entarteten Fall. Und das sieht man tatsächlich auch.
So, das war aber nur die untere Schranke.
Obere Schranke geht genauso, müssen sie nur andersrum abschätzen.
Dann schätzen sie den Logorithmus von 2hocha minus 1 ab durch
Minus i, minus 1. Und wenn sie das dann auflösen,
dann kommen sie auf N-Logorithmus zu Weiß, 2 von N plus 1.
So, das beißt für diese beiden Fälle,
entartet der Fall und den minären Baum, kennen wir die Potenziale ungefähr.
Die liegen nämlich für den Line-Anfall ungefähr bei N-Log N,
ja, und für den Binären suchbar zwischen N-Log 2,
N plus 1 und 2 N-Log 2 Intros 1, also ungefähr N.
Ja, das sind die Schranken, die wir haben.
Okay, aber das hat uns jetzt bezüglich der Analyse noch
keinen Schritt weitergebracht. Das war nur,
um mal zu sehen, wie verhält sich denn diese Potenzialfunktion
für diese beiden Extremfälle
So, dann, der nächste Schritt ist, wir müssen zeigen,
Potenzial ist immer positiv, das ist offensichtlich der Fall,
das müssen wir nicht mehr groß zeigen,
können auch mal die Potenzialfunktion angucken,
also das S ist immer positiv,
der Logorithmus ist immer positiv und dann haben wir, also vorausgesetzt,
das S ist größer als eins und das ist ja Logorithmus positiv und hier haben wir dann entsprechend das Potenzial.
Okay, so, nun Ja,
jetzt müssen wir die Play-Operation angucken und wir wissen bei der Funktion mit dem,
mit der amortisierten Analyse funktionierte das so, dass wir gesagt haben,
okay, die amortisierte Laufzeit für die Operation sind die realen Kosten plus Potenzialdifferenz,
ja, also fiestrich-minus-vieh, ja, das hat,
so funktionierte das.
Wir werden jetzt quasi die einzelnen,
die drei Operationen in der Play-Operation getrennt analysieren und schauen,
wie viel Laufzeit brauchen die,
also wie lange brauche ich für einen Sick-Fall,
einen Sixig-Fall und einen Six-Seck-Fall,
Und das ist das Access-Lemmer. Und wenn man
das geschafft hat, dann ist der Rest relativ einfach.
Dann ergibt sich der Rest eigentlich von selbst. Okay,
also in einer Sequenz von Splay-Operationen auf einem Warm mit Wurzel,
Tee, ist die amortisierte Anzahl von Rotationen in der Splay-Operation
maximal dreimal rvonte-r von x plus 1.
Also R-Fontee ist sehr rang. Ja,
also das war ja der Logarithmus dieser Größe, ja,
also Log-in, sozusagen für die Wurzel.
Und x ist der Rang von dem Knoten,
den wir quasi hochsortieren
Ja. Und dann ist die amortisierte Laufzeit O von Lock,
S von T durch S von X.
Das ist nur nochmal das Einsetzen. Das werden wir nachher
sehen. Ja, also das muss man nur noch,
das R und das S hat mir eine logerithmische Beziehung zueinander.
Also der Rang ist der Logerithmus der Größe. Und wenn
sie hier R von T minus R von X haben und sie haben den Logerithmus davon,
dann haben sie natürlich S von T durch S von X. Okay,
so, wir betrachten die drei Rotationsoperationen und schauen, was jeweils passiert.
Was passiert mit den Rängen? Das erste ist diese SIG-Operation.
Das ist die Situation vorher, die ist der Knoten X,
hier ist der Uknoten Y, wir machen unsere Rechtsrotation.
Das ist die Situation nachher. X ist hier,
die Wurzel Y wird rechtes Kind und die Knoten hier verlagern sich alle so ein bisschen.
Und wir wissen, diese Operation kostet uns eine Zeiteinheit.
Wir müssen eine Rotation machen. Also wir messen die Anzahl
der Rotationen, die nötig sind.
Okay, also eine Zeiteinheit für die realen Kosten plus Potenziallifferenz.
Potenzial nachher ist, naja, der Rang der Knoten X und Y nachher.
Natürlich auch die Ränge von allen anderen Knoten,
aber die Ränge von allen anderen Knoten hier,
die haben sich alle nicht geändert
Ja, die sind alle gleich geblieben. Alles, was hier unten entsprechend ist.
Alles, was da drüber ist natürlich auch. Also deswegen,
das Einzige, was sich ändert, sind die Ränge von X und Y. Ja,
und dann haben wir die Ränge von X und Y nachher minus die Ränge von X und Y vorher.
Ja, so, und das können wir jetzt umformen und sagen,
okay, hier wissen wir,
der Rang von X nachher ist genauso groß wie der Rang von Y. Ja,
weil der Rang beschreibt ja nichts weiter als der Lokorithmus von dem ganzen Baum,
der da drunter hängt.
Ja, und hier hängt jetzt alles X und Y und A, B,
C da drunter und hier hängt unter Y X und Y und alles ABC.
Das ist also das Gleiche. Das heißt,
er Strich von X ist das Gleiche wie er von Y.
Und dann heben sich die zwei schon mal auf.
Bleibt also eins plus, erstrich von Y minus R von X.
Dann können wir sehen, dass er Strich von X
größer gleicher Strich von Y ist klar, weil er Strich ist ja jetzt die Wurzel oder der Vorgänger.
Deswegen ist der Rang von dem,
die Größe hier ist viel größer als von Y. Also ist das größer und dann können wir damit entsprechend das Y,
erstrich von Y, durch das S-Strich von X ersetzen und dann steht da diese Eins plus dreimal,
Strich von x-r von x, warum da jetzt das dreimal reinkommt,
das ist ja eine größere Abschließung,
das hat nur was damit zu tun, dass wir,
ja, das hier zeigen wollen.
Also wir wissen, wir sehen, es ist sogar
viel weniger, aber naja, das wollten wir zeigen.
Das ist dreimal eher von T-R von x plus 1.
Also das ist jetzt erstmal um den einen Knoten zu verschieben. So,
das war der SIG-File und jetzt kommen die anderen beiden Fälle,
die machen wir genauso wie hier,
nur wir müssen zwei Operationen haben und wir verschieben mehr Knoten.
Deswegen ist es ein bisschen komplizierter zu rechnen. So,
das ist SIG-SIG, also x, y,
wir schieben erstmal x auf die Position Y und dann hoch,
das wird der Baum, der rauskommt.
Hier haben wir immer er, hier haben wir das Potenzial danach, erstrich.
So, was passiert? Reale kosten zwei, zwei Rotationen
müssen ausgeführt werden. Potenzial nachher, erstrich von X-Bus,
Strich von Y plus, erstrich von Z, Minuspotenzial vorher,
AirPhone X plus, R von Y plus R von Z.
Alle anderen Knoten ändern ihr Potenzial nicht. So, und
jetzt brauchen wir wieder so ein paar Tricks. Wir sehen,
Strich von XSR von Z, also X ist neue Wurzel,
das Potenzial von dem ist genauso wie das,
was wir vorher hatten.
Also die Anzahl der Knoten, die hier drunter hängen,
ist die gleiche wie hier
Dann heben sich wieder die beiden Therme auf. Mich wird
es schon ein bisschen kompakter. Dann haben wir zwei plus
erstrich von Y plus erstrich von Z minus zwei RX.
Wenn wir annehmen, wenn wir wissen,
dass er von Y größer gleich R von X ist,
weil Y ist ja eher von Y ist Vorgänger von X. Deswegen können wir das entsprechend abschätzen.
So, und jetzt kommt der Trick. Jetzt müssen wir
aus diesen beiden, Strich von Y und R-Strich von Z,
also aus den beiden müssen wir etwas machen, was von X abhängt.
Und dazu bebrauchen wir unser Lämmer 3. Dieses Lämmer 3
war das, ja, das brauchen wir jetzt.
Also das heißt A plus B ist kleiner,
gleich C und daraus folgt das Lock A plus Lock
B ist kleiner, gleich 2 Loch C minus 2.
Das ist diese Umrechnung, die wir gebraucht haben.
So, wie können wir die jetzt nutzen? Wir schauen,
also in diesem Fall, also diesen Schritt müssen wir machen,
von hier nach hier und hier unten steht,
wie das geht
Wenn wir die Six-Sack-Operation gemacht haben, ist X,
ein Elternknoten von Y und Z. Ja, die sind beide Kinder.
Deswegen ist die Größe von X die Größe von Y plus
die Größe von Z plus das Gewicht von dem Knoten X selber.
Also die Größe von dem, plus die Größe von dem,
plus die Größe von dem. Also ist S-Strich von X größer,
gleich S-Strich von Y plus S-Strich von Z.
Jetzt gucken wir uns aber gar nicht die Größe an,
sondern in den Rang, was ja der Logorithmus davon war.
Also können wir sagen, wir benutzen jetzt,
das ist jetzt unser A,
B und C, das ist A,
das ist B,
das ist
Was setzen wir jetzt da ein? Und dann wissen wir,
dass der Logorithmus von S-Strich von Y plus der Logorithmus von S-Strich von Z,
kleiner gleich zweimal, der Logorithmus von C,
das ist S-Strich von X, minus zwei ist.
So, und das sind genau unsere Ränge,
also steht hier eher Strich von Y plus S-Strich von Z,
kleiner gleich zweimal S-Strich von X, minus zwei.
Und jetzt kommt der Clou an der ganzen Geschichte.
Das können wir hier einsetzen, ja. Hier kommt
die minus zwei rein, durch diesen Logorithmen-Trick, ja.
Und die minus zwei hebt sich auf mit den realen Kosten,
die wir vorne haben
Die beiden gehen raus. Und was dann übrig bleibt,
ist dreimal der Strich von X plus R von X. Okay,
so, das kann man jetzt noch nicht so genau erkennen,
warum das das Entscheidende ist, aber das ist es,
also ich sag's ihnen jetzt einfach mal, das ist das Entscheidende.
Hier darf kein konstanter Faktor mehr reinkommen,
weil nur wenn der konstante Faktor fällt, können wir gleich,
dadurch, dass wir das aufsummieren zu der logorithmischen Schranke kommen.
Jetzt wollen wir erst noch die Sixig-Operation,
wir machen wieder das Gleiche, wir rechnen genau die gleiche Geschichte,
wir gucken uns den Fall ab,
XYZ ändern ihre Höhen, wir haben X,
YZ,
danach mit den Rängen
eher Strich
Und wir setzen wieder ein, reale kosten zwei, Potenzial nachher,
Potenzial vorher. Erstrich von XSR von Z, also hier,
erstrich von X, der ganze Baum, erstrich R von Z,
der ganze Baums, also gleich, hebt sich auf.
Er von Y ist größer gleich R von X,
Y ist ein Vorgänger von X,
dann können sie die zusammenfassen und jetzt können sie noch zeigen,
dass er Strich von X größer gleich,
er Strich von Y ist, weil X der Vorgänger von Y ist,
dann steht da zwei plus Erstrich von X plus R-Strich von Z minus zwei RX und dann machen wir wieder unseren Trick mit die Lämmer 3,
rechnen das wieder um und können das wieder einsetzen,
den Rechenschritt und dann hebt sich die minus 2 wieder auf.
Wir haben hier erstrich von x-r von x.
Das ist also genau das Gleiche wie im Zicksack-Fall.
So, okay, so, soweit so gut.
Damit haben wir im Prinzip gezeigt, was wir für eine Einzeloperation brauchen.
Jetzt müssen wir natürlich noch in dem ganzen Baum langlaufen
bis nach oben und das alles addieren. Bevor wir,
nein, das machen wir jetzt, das heißt,
wir haben jetzt in der Splay-Operation eine Sequenz von K Zig oder 6-Sack oder 66-Operation.
Wir laufen jetzt so langsam nach oben. Mit dem X,
ja. Okay, so. Der Knoten X wird schrittweise
bis zur Wurzel rotiert. Hochrotiert. Und nach jeder Operation
haben wir jetzt so eine R-Funktion, das ist Potenzial,
das ist R von I. Das ist also die R-Funktion nach Ausführung der Iten-Z-Operation.
Das ist irgendwie eine von diesen Dreien. Deswegen steht hier ZXX.
Und wie viele Rotationen brauchen wir jetzt insgesamt? Naja,
die Anzahl der Rotationen insgesamt ist also die Summe über all diese Schritte,
I gleich 1 bis K und dann hier die Anzahl der Rotationen,
die wir brauchen, Für die IT-Operation, wie immer die aussieht.
Von der wissen wir, die Maximalzeit,
und zwar für die letzte SIG-Operation,
ist es dreimal R von x-minus R von x-plus 1. Ja,
also das ist sozusagen die letzte Operation.
Und hier haben wir jeweils die SIX-SIG oder die 66-Operation.
Und die haben keinen konstanten Term mehr. Und über die
müssen wir jetzt so summieren von IGAX 1 bis K minus 1.
Und das ist eine Teleskopsumme. Und da bleibt dann
genau über dreimal der zum Zeitpunkt K von X minus
dreimal erst zum Zeitpunkt 0 von X plus 1.
Und X ist am Ende die Wurzel, deswegen ist das eher von Tee.
Und vorher ist es irgendwo im Baum, also eher von X.
Und das ist genau das, was das Accesslammer sagt.
Das sagt quasi, was uns die Splay-Operation besuche ich
der Anzahl der Rotationen kostet. Okay, Slater und Touchdown
haben dann sogar gezeigt, dass diese Schranke scharf ist.
Also für die CXIC-Operation ist die scharf.
Sie können Fälle konstruieren, wo sie genau diese Anzahl von Rotationsoperationen
auch benötigen
Das Bemerkenswerte an dieser ganzen Konstruktion ist für mich die Bedeutung
dieser Zahl hier, dieser konstanten Addition von diesen zweien.
Weil nur dadurch, dass wir hier diese zwei einsparen,
können wir in der Summe es nachher erreichen,
dass wir mit der Teleskopsumme das gewünschte Ergebnis erreichen.
Das muss man sich einfach nochmal überlegen. Okay,
so, als ich das nochmal mir genau angeguckt habe,
habe ich dann gedacht, ja okay,
geht auch bei der Move-to-Root-Heuristik wahrscheinlich genauso.
Ist ja nur die eine Operation, die anders ist.
Warum können wir
das nicht
auch machen
Okay, wir machen hier, das war der Sixig-Fall,
wir machen jetzt move to root. Da haben wir den
Fall. Move to root würde jetzt diesen Baum konstruieren.
Wir machen genau den gleichen Schritt. Und wir überlegen uns wieder,
kommt denn da, wenn da jetzt auch das rauskommt,
hier, ja, dann wäre super,
dann hätten wir ja da auch die suggerithmische Laufteile erreicht.
Faszinierenderweise geht es tatsächlich nicht. Muss ja auch nicht gehen,
weil wir wissen ja schon, dass es Fälle gibt.
Also wir haben es hier nicht gezeigt,
aber ich habe es Ihnen gesagt, dass es Fälle gibt,
wo wir im Worst Case eben den Jahre Zeit haben.
Wenn Sie in diesem Fall den gleichen Trick machen,
zwei plus, und dann sagen Sie das Potenzial nachher,
Minuspotenzial vorher, Der Schritt geht auch noch.
Also sie wissen, dass das R von Set das gleiche ist wie Strich von X.
Können sie auflösen? Dann kommen sie zu dieser Formel. So,
und jetzt kam ja der Rechentrick, wo sie dann abschätzen,
wo sie dann die Therme gegeneinander abschätzen in dem Baum
und dadurch durch diese zu der schlussendlichen Form gekommen.
Sie müssen irgendwie das R-Strich von Y und das R-Strich von Set abschätzen durch K,
also irgendein Faktor mal R-Strich von X. Ja,
das müssen sie erreichen.
Dann könnten sie die Analyse machen. Das geht auch.
Allerdings verschwindet der konstante Therm nicht. Sie kriegen es nicht
hin so, dass sie diese minus zwei haben am Ende
Sie kriegen die Umformung nicht hin.
Und deswegen können sie zumindest mit dieser Analyse-Methode nicht zeigen,
dass das Move to Root eben auch in der gleichen Laufzeitschranke läuft.
Geht nicht. Es könnte natürlich sein, dass es
mit einer anderen Analyse-Technik geht. Deswegen brauchen wir natürlich noch
einen anderen Beweis, dass es wirklich schlechter ist.
Aber zumindest können wir die Technik, die wir hier gesehen haben,
auf Move to Root nicht anwenden.
Okay, so, jetzt haben wir es fast geschafft.
Jetzt brauchen wir das Access Land mal nämlich nur noch einsetzen.
Ja, und kriegen dann sofort unsere Laufzeiten raus
Okay, also mit dem Exoslammer können wir die amortisierten Laufzeiten zeigen.
Wir haben Gewichte wie von I. Diese Gewichte können wir ja noch beliebig festlegen.
Die waren, ich habe mit meinen Beispielen,
war das immer eins, aber die haben die ganze Zeit
keine Rolle gespielt und wir können da was einsetzen,
was wir wollen.
Okay, so, wir haben M-Zugriffsoperationen auf einem Splaytree mit N-Knoten
und wir benötigen dazu im Worst Case O von M plus N mal Log-in plus M-Zeit.
Wie machen wir das? Also wir gehen mal als
nötige Gewichtsfunktion von eins durch N aus,
also wir verteilen sozusagen ein Gesamtgewicht von eins
auf alle Knoten
Und dann können wir gucken,
wie groß ist der Potenzialverlust durch eine Sequenz von solchen Splay-Operationen und dann wissen wir,
naja, im ungünstigsten Fall haben wir ein Blatt,
das ist an der Position,
das hat dann ein Gewicht von eins durch N,
wenn es hier ganz unten ist, ja, das ist nur der Knoten selber.
Und wenn das dann geht das hoch bis zur Wurzel,
ja, und wenn es an der Wurzel ist,
dann haben wir ein Gewicht von eins, ja, weil dann alle Knoten da drunter sind.
Das heißt, der maximale Potenzialdifferenz ist für alle Knoten,
das ist jetzt eine grobe Abschätzung, ne,
N mal das Maximum, also vom Blatt,
hoch bis zur Wurzel, ja,
also das ist weh durch das W von ihm und das W
wäre dann eins und das W von ihm wäre eins durch N,
macht also insgesamt N mal Login,
Okay. Ja, hier ist nochmal die Begründung,
maximale Größe ist gesamt weh, wenn es die Wurzel ist,
minimale Größe ist die eines einzelnen Knotens, also eins durch einen.
So, jetzt können wir es einsetzen.
Dann haben wir die Gesamtlaufzeit von, abhängig von MN.
Das ist also zehnmal die Laufzeit für die Splay-Operation, für M-Operation.
Wir haben gesehen, es ist ja proportionalstes Play,
Operation minus die oder plus die Potenzialdifferenz,
also plus Potenzial nach den M-Operationen, minus Potenzial vor den M-Operationen.
Die Potenzialdifferenz haben wir schon abgeschätzt,
ist also kleiner als N-Log-in
Und für die Splay-Operation setzen wir jetzt unsere Formel ein.
Das ist diese Formel mit den Rs,
aber wenn wir dann schon den Logarithmus davon nehmen und die Größe,
dann haben wir das hier stehen.
Das ist also die Logarithmus,
der Logarithmus von der Größe des Teilbaums von der Wurzel,
geteilt durch die Größe des Elements XI.
Das können wir wieder abschätzen hier. Die Wurzel hat immer
eins, SI von XS höchstens N. Und dann können wir
die Summe hier entsprechend auflösen und dann haben wir Konstanten,
mal M, mal Log NW,
plus wieder konstanten,
mal M plus N-Log N
von der Potenziallifferenz
Und dann setzen wir für wen noch eins ein und kriegen dann die Laufzeitschranke.
Okay, das ist quasi die, das ist der Kern
der Analyse des Splay-Algorithmus. Man kann das auch noch anders machen,
man kann zum Beispiel, wenn man die Zugriffshäufigkeiten weiß,
also wenn wir wissen, wie häufig ein spezielles Element aufgerufen ist,
kann man noch andere Gewichte verwenden,
dann kommt man zu dieser Static Optimality, also zur Statistischen Optimalität.
Das heißt, wenn QI die Zugriffshäufigkeiten für ein Objekt ISIS,
Ja, dann kann man zeigen,
dass die Gesamtlaufzeit O von M plus und dann die Summe
Idaich 1 bis M QI mal Log M durch Coolie ist.
Und das macht man, indem man nur eine einzige Sache ändert.
Man ändert nur das Gewicht, man schafft statt einer Gleichverteilung von 1 durch N.
Das ist ja mehr oder weniger 1 durch N,
wäre ja die Zugriffswahrscheinlichkeit bei gleichverteilten Zugriff.
Also jedes Objekt wird gleich häufig eingefragt.
Statt der nehmen wir jetzt also die vorgegebene Zugriffswahrscheinlichkeit QI durch M.
Also M ist ja die Anzahl aller Zugriffe und QI
durch M wäre dann die Wahrscheinlichkeit,
das IT-Objekt dann anzufragen
So, und dann können wir das auch wieder da einsetzen.
Und der ganze Rechenweg ist eins zu eins identisch mit dem,
was wir gerade gesehen haben. Außer,
dass wir hier für SI von Tee, da kommt natürlich wieder eins raus,
weil die Summe aller Zugriffe ist natürlich wieder gerade M,
die Summe aller Operationen.
Und dann können wir also hier wieder eins einsetzen,
hier für ein einzelnes Objekt eben QI durch M,
für das ETO-Objekt, können dann hier die Summen bilden,
das auflösen und kriegen dann genau diese geschlossene Formel heraus.
Okay, was machen Insert und Delete? Wir haben also noch diese zwei Operationen,
die Wir betrachten müssen, also auch einfügen und löschen,
produzieren ja potenziell Kosten, ändern das Potenzial, ja.
Wir gucken uns mal die Insert-Funktion an. Die Insert-Funktion macht
eine Splay-Operation und dann fügt es das X als neue Wurzel ein.
Jetzt müssen wir gucken, was passiert jetzt mit unserem Potenzial.
Okay, die amortisierten Kosten für die Splay-Operationen kennen wir schon. Ja,
das haben wir ja ausgerechnet,
das ist irgendwie dreimal eher von T minus R von X-Strich
plus 1 und dann haben wir noch die Potenzialdifferenz und 4X
ist dann die Potenzialfunktion,
nachdem das Objekt eingefügt wurde und X ist quasi
das Potenzial vorher
Und dann können wir uns überlegen, ja,
das Potenzial nach dem Einfügen ist quasi alle Knoten des Baums mit dem Knoten X noch dazu.
Der wird ja neue Wurzel, das heißt,
alle Knoten behalten ihr Potenzial, rutschen halt nur nach unten.
Ja, und minus quasi die Ränge von den Knoten vorher.
Da bleibt also nur das R von X hier übrig.
Ja, und dann können sie das einsetzen.
Hier wieder für das R, der Logorithmus der Größe,
der Bäume und das R-Phone X hier ist auch der Logorithmus von
der Größe und wir können WI zum Beispiel mal auf eins setzen für alle Knoten,
dann wäre für den Wurzelfloten wäre das N-minus 1.
Und wenn sie das einsetzen, kriegen sie genau Log-in für
die einen Füge-Operation. Und bei Löschen geht es genauso,
da machen sie zweimal die Splay-Operation. Ja,
dann entfernen sie die Wurzel und hängen den rechten Teilbaum um.
Das war der Algorithmus. Und wenn wir jetzt Asplay betrachten,
dann wissen wir, die müssen wir also zweimal ausführen.
Wir haben also die Lead-Kosten. Das ist die amortisierten Kosten
fürs Play. Die amortisierten Kosten nochmal fürs Play,
allerdings für den Linken Teilbaum plus das Potenzial nachlöschen von x,
minus das Potenzial vorher
Und das können wir wieder einsetzen. Hier sind die Kosten für
die Splay-Operation hier, die es kosten für den linken Teilbaum.
Und hier jeweils die Potenziale vor dem Löschen und nach
dem Löschen und vor dem Löschen.
So, hier heben sich wieder alle Knoten auf,
außer die Knoten X und Y. Das sind die an der Wurzel.
Die heben sich nicht auf, dann wissen wir aber,
Airphone X ist größer, als dass er Strich von Y.
Und damit ist diese Summe hier insgesamt negativ.
Können wir dann also abschätzen,
fällt weg
Dann haben wir das hier stehen,
wir können wieder eins einsetzen als Gewicht, als Beispiel.
Dann ist S von T gleich N und der Linke
ist irgendwie etwas kleiner als N. R von X wäre größer
gleich eins und R Y auch größer gleich eins.
Und wenn wir das einsetzen, kommt wieder Login raus.
Okay, amortisiertes Einfügen und Löschen geht in logorithmischer Zeit und die Anfragen eben auch.
Okay, damit hat man die Datenstruktur vollständig analysiert.
Es folgt eben dieses Balance-Theorien, der Splaytrees,
das heißt in Splaytree, ermöglicht die Ausführung von M-Wörterbuchoperationen.
Das ist entweder Innensatellit oder Search auf einem Initiallehrenbaum,
sonst geht es natürlich nicht
Mit maximal N-Objekten im Wörterbuch während der Ausführung in amortisierter Zeit
von O von M-Login. Und das ist mehr oder weniger
nur eine Zusammenfassung von dem, was wir gesehen haben.
Okay, das ist richtig heftig. Ja,
also das ist eine richtig schwierige Analyse und vor der ziehen viele Informatiker auch den Hut,
weil man wirklich mit einer algorithmischen Situation konfrontiert ist,
von der man nicht ausgehen kann, dass es tatsächlich irgendwie überhaupt funktioniert.
Von dieser Situation auf diese Potenzialfunktion zu kommen,
Es ist ein riesiger Schritt. Danach ist es Nachrechnen.
Und zwar geschicktes Nachrechnen. Durch solche Tricks hier haben sie
es dann rausgekriegt, dass sie die Konstanten entfernen konnten.
Aber dann hat man es geschafft. Aber der Glaube daran,
dass es geht und die Potenzialfunktion zu finden,
mit der man das dann zeigen kann, ist der richtig schwierige Teil.
Diese Play-Operation sind gut bei Unless gleichmäßiger Verteilung der Suchanfragen.
Also wenn sie nicht wissen, wie häufig was angefragt wird.
Und natürlich setzt es voraus, dass sie Objekte haben,
die dann häufig angefragt werden. Und durch die häufige Anfrage
nach oben rutschen. Das macht die Splay-Operation aus. Einfache Operation,
leicht zu implementieren, sogar hardwarenahe Implementierung ist möglich.
Es war damals sogar das Ziel. Also das Ding in Hardware
zu bauen. Aber es gibt wie immer ein großes Aber.
Was machen die Konstanten? Wenn die Algorithmen pfiffig werden,
die Analysen kompliziert, geht es meistens auf die Konstanten.
Und hier ist es auch wieder so. Die Konstanten gehen hoch. Das heißt,
wenn wir im Wesentlichen eine gleiche Verteilung der Daten haben,
dann wissen wir, naja, wir greifen dann immer auf diesen warm zu.
Wenn wir insbesondere ganz viele Suchanfragen haben,
nur ganz wenig einfügen und löschen, was ja auch typisch ist für Anwendungen,
da sind natürlich balancierte Suchbäume wie Rot-Schwarz-Bäume eindeutig besser.
Weil wenn sie nur ganz wenig einfügen und löschen und ganz häufig anfragen,
dann würden sie bei einem Rot-Schwarz-Baum,
natürlich haben sie immer locker in Anfragezeit, okay,
sie rearrangieren den Baum nicht.
Aber bei gleichmäßiger Verteilung bringt ihnen das Rearrangieren natürlich auch nichts.
Und sie brauchen in den Suchanfragen nicht die ganzen Rotierungen.
Die Rotation, um den Knoten wieder hoch zu rotieren.
Das heißt, bei gleichmäßiger Verteilung lohnt sich
das ganze Konzept natürlich
Natürlich eher nicht. Aber wenn sie tatsächlich so eine
sehr ungleichmäßige Verteilung haben, dann ist es besser.
So, beim Umorganisieren der Bäume, die Play-Operation,
hat immer O von H viele Rotationsoperationen.
Also sie rotieren immer so viel, um den Knoten nach oben zu kriegen.
Das kostet Zeit. Ja, und das machen sie eben
auch bei den Anfragen. Nicht nur beim Einfügen und Löschen,
während sie beim Rot-Schwarz-Raum nur beim Einfügen und Löschen rotieren und
ansonsten einfach nur die Suchanfragen machen.
Ja, okay, das war es zum Splaydree
Und damit werden wir die Bäume erstmal hinter uns lassen.
Wir werden nochmal zu den Bäumen zurückkehren. Am Ende
dieses Kapitels. Und zwar, die Frage ist natürlich,
was wäre eigentlich, wenn ich die Verteilung schon kenne?
Ja, also wenn sie den Suchbau bauen und zu
dem Zeitpunkt schon wissen, wie häufig was angefragt wird.
Dieser Splaitry funktioniert ja so, dass sie nur von einer
ungleichmäßigen Verteilung ausgehen, aber die Verteilung natürlich explizit nicht nutzen.
Sie fügen die Objekte ein Und nur dadurch, dass sie
ein Objekt immer häufiger anfragen, steht das eben weiter oben im Baum.
Aber was ist, wenn sie vorher schon wissen, naja,
das ist der Bestseller in meinem Buchkatalog und der wird eben am häufigsten angefragt.
Wenn sie diese Verteilung schon haben,
dann müssten sie ja nicht mit einem willkürlichen Baum anfangen und dann durch die Suchanfragen das optimieren,
sondern sie könnten ja von vornherein schon sagen,
ich lege die Objekte auf die Ebenen, die dementsprechend,
wie häufig sich das anfragen würde.
Und das, wenn wir uns nochmal anschauen,
das führt uns nochmal zu einem anderen Baum,
zu sogenannten Trips
Aber bevor wir die machen, Sie sehen schon einen Tree,
hat nicht nur was mit einem Tree,
sondern auch mit einem Hieb zu tun, bevor wir die machen,
müssen wir uns erst nochmal die Hiebs genau angucken.
Und dann kommen wir nochmal zu den Bäumen zurück und können schauen,
was wir machen können für den Fall, dass wir tatsächlich diese Verteilungsfunktionen kennen.
Okay, so, das heißt, Heebs müssen wir machen,
das werden wir heute nicht mehr groß anfangen.
Ich werde Anfang der nächsten Vorlesung fünf bis zehn Minuten mal auf den klassischen alten,
vinären Hieb zurückkommen und das nochmal ganz schnell wiederholen,
aber der ist ja eigentlich so einfach,
wahrscheinlich alle präsent haben und dann werden wir uns mal anderen Hiebs,
also anderen Prioritätswarteschlangen, die zu anderen Hieb aus anderen Hieb-Implementierungen führen,
zuwenden, um zu sehen,
dass man tatsächlich Algorithmen wie kürzeste Wege suche oder Spannbaumberechnungen nicht unbedingt in M-Login-Zeit durchführen muss,
sondern tatsächlich in M-Plus-N-Log-End-Zeitlauf durchführen kann.
Das hängt nämlich alles immer nur am Hieb. Okay,
aber das machen wir dann in der nächsten Vorlesung
und das war es dann für heute