Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

48
1 Kapitel 6: Suchbäume und weitere Sortierverfahren 6.1 Binäre Bäume Die Klasse BinTree mit Traversierungsmethoden 6.2 Suchbäume 6.2.1 AVL Bäume 6.3 HeapSort und BucketSort 6.3.1 HeapSort 6.3.2 BucketSort

description

Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume Die Klasse BinTree mit Traversierungsmethoden 6.2   Suchbäume 6.2.1   AVL Bäume 6.3   HeapSort und BucketSort 6.3.1   HeapSort 6.3.2   BucketSort. 6.1    Binäre Bäume (Fortsetzung). Eigenschaften: - PowerPoint PPT Presentation

Transcript of Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

Page 1: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

1

Kapitel 6:  Suchbäume und weitere Sortierverfahren

6.1   Binäre Bäume

Die Klasse BinTree mit Traversierungsmethoden

6.2   Suchbäume

6.2.1   AVL Bäume

6.3   HeapSort und BucketSort

6.3.1   HeapSort

6.3.2   BucketSort

Page 2: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

2

6.1    Binäre Bäume (Fortsetzung)

Eigenschaften: • Maximale Höhe eines Binärbaumes mit n

Knoten ist n-1.

(Wenn jeder innere Knoten genau ein Kind hat, liegt eine lineare Kette vor.)

• Minimale Zahl der Knoten eines Binärbaumes der Höhe h ist h+1.

(Dito)

Page 3: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

3

• Maximale Zahl der Knoten eines Binärbaumes der Höhe h: N(h) := 2h+1 - 1  Knoten.

Beweis: durch Induktion.

• Minimale Höhe eines Binärbaumes mit n Knoten: O(log n) bzw. genauer: [log2 (n+1)]+ - 1. Begründung: Sei h die minimale Höhe eines Binärbaumes

mit n Knoten. Dann ist:   2 h - 1 = N(h -1) < n N(h) = 2 h+1 - 1

also 2 h < n + 1 2 h +1

also h < log2 (n+1) h+1

Page 4: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

4

Satz: In einem nichtleeren Binärbaum T, dessen innere Knoten jeweils genau zwei Söhne haben, gilt #(Blätter(T)) = #(innere Knoten(T)) + 1.

Beweis: durch Induktion über die Größe des Baumes T.

Induktionsanfang: T Baum mit einem Knoten. Dann

#(Blätter(T)) = 1, #(innere Knoten(T)) = 0. Also Beh. OK.

Induktionsschluss: T Baum mit mehr als einem Knoten. Dann ist die Wurzel ein innerer Knoten. Seien T1 und T2 der linke und der rechte Teilbaum. Beide sind nicht leer. Nach Induktionsannahme #(Blätter(Ti)) = #(innere Knoten(Ti)) + 1 für i=1,2. Wir erhalten:

#(Blätter(T)) = #(Blätter(T1)) + #(Blätter(T2))

= #(innere Knoten(T1)) + 1 + #(innere Knoten(T2)) + 1

= #(innere Knoten(T)) + 1.

Page 5: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

5

ADT-Spezifikation (BinTree):

algebra BinTree sorts BinTree, El, boolean ops emptyTree: BinTree isEmpty: BinTree boolean isLeaf: BinTree boolean makeTree: BinTree x El x BinTree BinTree rootEl: BinTree El leftTree, rightTree: BinTree BinTreesets BinTree = {<>} + {<L,x,R> | L,R BinTree, x El } functions emptyTree() := <> makeTree(L,x,R) := <L,x,R> rootEl(<_,x,_>) := x ...end BinTree.

Page 6: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

6

"Linearisierung" von Binärbäumen(„Traversierungsmethoden“, Durchlaufen) :

ops inOrder, preOrder, postOrder: BinTree List

functions inOrder(<>) = <> preOrder(<>) = <> postOrder(<>) = <> (leere Liste)

inOrder(<L,x,R>) = inOrder(L) + <x> + inOrder(R) preOrder(<L,x,R>) = <x> + preOrder(L) + preOrder(R) postOrder(<L,x,R>) = postOrder(L) + postOrder(R) + <x>

wobei "+" die Listen-Konkatenation bezeichnet

Page 7: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

7

Beispiel: Binärbaum zum Ausdruck ((12/4)*2)

• inOrder: 12, /, 4, *, 2

• preOrder: *, /, 12, 4, 2

• postOrder: 12, 4, /, 2, *

Page 8: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

8

Implementierung in Java

public class BinTree {

private Object val; private BinTree right; private BinTree left; // Konstruktoren: BinTree(Object x) { val = x; left = right = null; }

BinTree(Object x) { val = x; left = right = null; }

BinTree(Object x, BinTree LTree, BinTree RTree) { val = x; left = LTree; right = RTree; }

Page 9: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

9

// Basismethoden (entspr. Signatur): public boolean isLeaf() { return ( this.left == null && this.right == null ) ; } public Object nodeVal() // entspr. "rootEl" { return this.val; } public void setNodeVal(Object x) // zusaetzlich { this.val = x; } public BinTree leftTree() { return this.left; } public BinTree rightTree() { return this.right; } public static boolean isEmpty(BinTree T) { return ( T == null ); } public static BinTree makeTree(BinTree L, Object x, BinTree R) { return new BinTree(x,L,R); } }

Page 10: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

10

// Durchlaufen:

public static LiLiS preOrder(BinTree T)   { if ( isEmpty(T) )       return LiLiS.emptyList();     else       return conc3(list1(T.nodeVal()),                    preOrder(T.leftTree()),                    preOrder(T.rightTree()) );   }

Etc. 

// Hilfsmethoden fuer LiLiS-Objekte: private static LiLiS conc3(LiLiS L1, LiLiS L2, LiLiS L3)   { return LiLiS.concat(LiLiS.concat(L1,L2),L3); }     private static LiLiS list1(Object el)   { PCell Cel = new PCell(el);          return new LiLiS(Cel);   }

Page 11: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

11

Array-Darstellung:

Neben einer Darstellung mit Zeigern auch direkt in einem Array:

Für links-vollständige Binärbäume: Knoteninhalte in der folgenden Reihenfolge in einen Array: von oben nach unten und in jeder Ebene von links nach rechts.

 Knoten mit dem Index i:• Linker Nachfolger: Index 2 i. • Rechter Nachfolger: Index 2 i + 1.• Vorgänger: Index i div 2.

Page 12: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

12

Beispiel zur Array-Darstellung:

Anmerkung: Das geht auch für nicht vollständige Binärbäume, aber dann gibt es Lücken im Array.

Page 13: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

13

Verallgemeinerung auf nicht-binäre Bäume:

Eine mögliche Definition:

Definition: Ein Baum T ist ein Tupel T = ( x, T1 , ... ,Tk ), wobei x ein zulässiger

Knoteninhalt und Ti Bäume sind.

Dabei ist auch k = 0 zugelassen. Der entsprechende triviale Baum besteht nur aus einem Knoten.

(Aber: Bei diesem Ansatz gehört null nicht zur Menge der Bäume!)

Page 14: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

14

Bezeichnungen und Eigenschaften:

• Grad eines Knotens: Anzahl seiner Kinder.• Grad eines Baumes T:

grad(T) = max { grad(k) | k Knoten in T }

• Die maximale Zahl von Elementen eines Baumes der Höhe h vom Grad d ist N(h) = (d h+1 - 1) / (d - 1).

Page 15: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

15

Implementierung:

• Über Arrays mit Zeigern auf die Kinder (nur wenn der Grad beschränkt und nicht zu groß ist).

• Über Zeiger/Binärbäume: Zeiger auf den am weitesten links stehenden Sohn und auf den Bruder rechts daneben, z.B.

class TreeNode {

private Object val;private TreeNode leftmostChild;private TreeNode rightSibling;...}

Page 16: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

16

6.2    Suchbäume

Dictionary-Operationen:

• member

• insert

• delete

Ziel: diese effizient implementieren

Page 17: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

17

Zum Vergleich:

member bei geordneter Liste als Array: durch binäre Suche

Geordnete Liste (Zeiger)

Ungeordnete Liste (Zeiger)

Geordnete Liste als Array

insert O(n) O(1) O(n)

delete O(n) O(n) O(n)

member O(n) O(n) O(log n)

Page 18: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

18

Definition:Sei T ein binärer Baum. N(T) bezeichne die Menge der Knoten von T.Eine Abbildung m: N(T) D heißt

Knotenmarkierung, wobei D ein Wertebereich mit einer vollständigen Ordnung ist.  

Ein binärer Baum T mit Knotenmarkierung m heißt genau dann Suchbaum, wenn für jeden Teilbaum T ' = ( L, x, R ) in T gilt:

y aus L m(y) < m(x) y aus R m(y) > m(x)

Beachte: alle Marken verschieden (Dictionary!).

Page 19: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

19

Implementierung:

Wir leiten die Klasse BinSearchTree von der Klasse BinTree ab.

Erweiterung (gegenüber BinTree): Markierungsfunktion numVal: BinSearchTree int

Dictionary-Operationen zu realisieren:   ops  member: El x BinSearchTree boolean

insert: El x BinSearchTree BinSearchTree delete: El X BinSearchTree BinSearchTree

Page 20: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

20

Insert

Algorithmus insert(Objekt x, Baum T)

{ falls T = leer dann

{makeTree(leer,x,leer); return};

falls ( m(x) < m(Wurzel von T) ) dann

insert(x, linker Unterbaum von T)

sonst

insert(x, rechter Unterbaum von T) }

Page 21: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

21

Member

algorithmus member(Objekt x, Baum T) {falls T = leer return false; int k = m(x); int k´ = m(Wurzel von T); falls k = k´ return true; falls k < k´ return member(x, linker Unterbaum von T) sonst return member(x, rechter Unterbaum von T)}

Page 22: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

22

Delete

Löschen (delete) eines Elementes: (Evtl. Umstrukturierung des Baumes.)1. Bestimme den Teilbaum T ', an dessen Wurzel sich das

zu löschende Element befindet. 2. Falls T ' ein Blatt ist, ersetze T ' in T durch null. 3. Falls T ' nur einen Unterbaum ( T '' ) besitzt, ersetze T '

durch T ''. 4. Sonst entferne das kleinste Element (min) aus dem

rechten Unterbaum von T ' (man beachte: min besitzt nur einen Unterbaum) und setze T '.val = min. (alternativ das größte Element aus dem linken Unterbaum)

Page 23: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

23

Komplexitätsanalyse

Sei n die Zahl der Knoten des Suchbaumes.

Kosten eines Durchlaufens: O(n)

Kosten von member, insert, delete:

nichtkonstanter Anteil: Suchen der richtigen Position im Binärbaum entlang eines Pfades von der Wurzel

O(Höhe des Baumes)

Page 24: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

24

• Best case: vollständiger Baum Höhe = O(log n). Komplexität der Operationen also auch nur: O(log n).

• Worst case: linearer Baum (entsteht z.B. durch Einfügen von vorsortierten Elementen)

Höhe = n-1. Komplexität der Operationen: für jede einzelne Operation: O(n), für den Aufbau des Baums durch Einfügen: O(n²).

Page 25: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

25

Komplexitätsanalyse (2)

• Average case: Komplexität der Operationen ist von der Ordnung der durchschnittlichen Pfadlänge (Mittel über alle Pfade in allen Suchbäumen mit n Knoten) = O(log n)

(siehe Skriptum: direkte Abschätzung oder Berechnung über die Harmonische Reihe)

Page 26: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

26

Gesucht: Mittlere Astlänge in einem durchschnittlichen Suchbaum. Dieser sei nur durch Einfügungen entstanden. Einfügereihenfolge: Alle Permutationen der Menge der Schlüssel a1, ... , an gleichwahrscheinlich. Diese wollen wir zunächst als sortiert annehmen. A(n) := 1 + mittlere Astlänge im Baum mit n SchlüsselnA(n) := mittlere Zahl von Knoten auf Pfad in Baum mit n Schlüsseln. Sei ai+1 das erste gewählte Element. Dann steht dieses Element in der Wurzel. Im linken Teilbaum finden sich i, im rechten n-i-1 Elemente. Linker Teilbaum ist zufälliger Baum mit den Schlüsseln a1 bis ai , rechter mit den Schlüsseln ai+2, ..., an. Die mittlere Zahl von Knoten auf einem Pfad in diesem Baum ist daher       i/n · ( A(i) + 1) + (n-i-1)/n (A(n-i-1) + 1) + 1·(1/n).

Page 27: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

27

Dabei sind die Beiträge der Teilbäume um eins vergrößert (für die Wurzel) und mit den entsprechenden Gewichten belegt. Der letzte Term betrifft den Anteil der Wurzel. Schließlich muss über alle möglichen Wahlen von i mit 0 ≤ i < n gemittelt werden. So erhalten wir     A(n) = n-2 [ ∑ 0 ≤ i < n [i (A(i)+1) + (n-i-1)(A(n-i-1)+1) + 1]

Aus Symmetriegründen ist der Anteil der beiden Terme A(i) und A(n-i-1) gleich, die konstanten Teile summieren sich zu n und 2(n-1)n/2 auf. Somit folgt

    A(n) = n-2( 2 ∑0≤i<n i A(i) + (n-1)·n + n) = 1+ 2n-2∑0≤i<n i A(i) Wir führen die Abkürzung S(n) = ∑0≤i<n i A(i) ein und erhalten         A(n) = 1 + 2n-2 S(n-1) und         S(n) - S(n-1)  = n A(n)   = n + 2 · S(n-1) / n ,

also die Rekursionsformel S(n) = n + S(n-1) · (n+2) / n.

Page 28: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

28

Rekursionsformel: S(n) = n + S(n-1) · (n+2) / nAußerdem ist S(0) = 0 und S(1) = A(1) = 1.   Nun wollen wir durch Induktion folgende Ungleichung beweisen:     S(n) ≤ n (n+1) · ln (n+1)  Sicherlich ist dies für  n = 0 und n = 1 richtig. Einsetzen der Rekursionsformel für n-1 ergibt aber beim Schluss von n-1 nach n:     S(n) = n + S(n-1) · (n+2) / n             ≤ n+(n-1) ·(n+2) ln n             = n(n+1) ln (n+1) + (n+1)n (ln n - ln (n+1)) - 2 ln n + n             ≤ n(n+1) ln (n+1) - (n+1) n / (n+1) - 2 ln n + n             < n (n+1) ln (n+1) Dabei haben wir ln n - ln (n+1) = -1/(n+θ), 0<θ<1, verwendet. Dann folgt aber     A(n) = 1 + 2n-2 S(n-1) ≤ 1+ 2 ln n = O( log n)

Page 29: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

29

6.2.1    AVL-Bäume (nach Adelson-Velskii & Landis, 1962)

Komplexität der Operationen member, insert, delete bei Suchbäumen im worst case: (n).

Geht besser! Idee: Balancierte Bäume.

Definition: Ein AVL-Baum ist ein binärer Suchbaum derart, dass

für jeden Teilbaum T ' = < L, x, R > gilt: | h(L) - h(R) | 1

(Teilbaum balanciert, AVL-Eigenschaft).Oft wir auch an den Knoten h(.)+1 annotiert.

Page 30: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

30

Ziele1. Wie erhält man die AVL-Eigenschaft beim

Einfügen und Löschen?

2. Wir werden für AVL-Bäume sehen:

Komplexität der Operationen im worst case

= O(Höhe des AVL-Baumes)

= O(log n)

Page 31: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

31

Erhaltung der AVL-Eigenschaft

Nach Einfügen und Löschen muss dafür gesorgt werden, dass der neue Baum wieder die AVL-Eigenschaft hat:

Rebalancieren.

Mittels: Rotationen und Doppelrotationen

Page 32: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

32

Rotation (hier für den Fall, dass der rechte Unterbaum nach einem insert rechts zu groß)

Page 33: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

33

Doppelrotation (hier für den Fall, dass der rechte Unterbaum nach einem insert links zu groß)

Page 34: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

34

Rebalancieren nach Einfügen:

Entweder der Baum ist noch balanciert oder:

Satz: Nach einer Einfügung genügt eine Rotation oder Doppelrotation des ersten* aus der Balance geratenen Teilbaums zur Wiederherstellung der Balance (AVL-Eigenschaft).

(* : auf dem Weg vom eingefügten Knoten zur Wurzel).

Denn: nach Rotation/Doppelrotation ist die ursprüngliche Höhe dieses Teilbaums wiederhergestellt!

Page 35: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

35

Rebalancieren nach Löschen:

Entweder der Baum ist noch balanciert oder:

Satz: Nach einer Löschoperation kann der erste* aus der Balance geratenen Teilbaum durch eine Rotation oder Doppelrotation wieder in Balance (AVL-Eigenschaft) gebracht werden.

(* : auf dem Weg vom entnommenen Knoten zur Wurzel). Aber: da die Höhe des Teilbaums sich dadurch um 1

vermindern kann, muss dies evtl. für den nächstgrößeren Teilbaum wiederholt werden, usw. bis zur Wurzel.

Page 36: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

36

Zur Implementation Bei der Suche nach einem aus der Balance geratenen

Unterbaum muss man nur weitersuchen (d.h. zum nächsthöheren Knoten gehen), wenn der zuletzt besuchte Unterbaum seine Höhe geändert hat.

Um ohne zusätzliches Durchlaufen von Knoten herauszufinden, welche Teilbäume nicht balanciert sind, merkt man sich bei den Knoten zusätzlich entweder die Höhe des Teilbaums oder die Balance (z.B. in der Form: Höhe(linker Unterbaum) – Höhe(rechter Unterbaum) ). Diese Daten müssen natürlich beim Einfügen und Löschen auch immer entsprechend geändert werden.

Es sollte eine Vorgängerfunktion implementiert werden.

Page 37: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

37

Komplexitätsanalyse – worst case

Sei h die Höhe des AVL-Baumes.

Suchen: wie beim Suchbaum, also O(h).

Einfügen: insert wie beim Suchbaum (O(h)) und vom eingefügten Knoten zur Wurzel zurück und höchstens eine (Doppel-) Rotation: auch O(h).

Löschen: delete wie beim Suchbaum (O(h)) und vom eingefügten Knoten zur Wurzel zurück und dabei evtl. eine (Doppel-)Rotation pro Knoten: O(h).

Also alle Operationen: O(h).

Page 38: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

38

Abschätzung der Höhe eines AVL-Baumes

Sei N(h) die minimale Zahl der Knoten eines AVL-Baumes der Höhe h.

N(0)=1, N(1)=2,N(h) = 1 + N(h-1) + N(h-2) für h 2.N(3)=4, N(4)=7 Erinnerung: Fibonacci-Zahlenfibo(0)=0, fibo(1)=1, fibo(n) = fibo(n-1) + fibo(n-2)fib(3)=1, fib(4)=2, fib(5)=3, fib(6)=5, fib(7)=8Durch Nachrechnen zeigt man:N(h) = fibo(h+3) - 1

0

12 3

Konstruktionsprinzip

Page 39: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

39

Sei jetzt n die Knotenzahl eines beliebigen AVL-Baums der Höhe h. Dann gilt:

n N(h) ,also mit p = (1 + sqrt(5))/2 und q = (1- sqrt(5))/2n fibo(h+3)-1 = ( ph+3 – qh+3 ) / sqrt(5) – 1 ( p h+3/sqrt(5)) – 3/2,also

h+3+logp(1/sqrt(5)) logp(n+3/2),also gibt es eine Konstante c mit

h logp(n) + c

= logp(2) • log2(n) + c

= 1.44… • log2(n) + c = O(log n).

Page 40: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

40

Die Höhe eines AVL-Baumes ist also nach oben beschränkt durch:

logp(2) • log2(n) + c = 1.44… • log2(n) + c.

Anmerkung: Für die maximale Höhe H eines AVL-Baumes mit n Knoten gilt:

N(H) n < N(H+1)Daraus folgert man ähnlich wie oben: H = logp(2) • log2(n) + c‘ = 1.44… • log2(n) + c‘. Die oben berechnete obere Schranke ist also scharf.

Fazit

Page 41: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

41

6.3.1 Heapsort

Idee: Zwei Phasen:

1. Aufbau des Heaps

2. Ausgabe des Heaps

Für aufsteigende Sortierung: Heap mit umgekehrter Ordnung, d.h. Maximum in der Wurzel (nicht Minimum).

Heapsort ist ein in-situ-Verfahren.

Page 42: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

42

Wiederholung:

Heap mit umgekehrter Ordnung:

• Für jeden Knoten x und jeden Nachfolger y von x gilt: m(x) m(y),

• links-vollständig, d.h. die Ebenen werden von der Wurzel her gefüllt, und jede Ebene von links nach rechts,

• Implementierung in einem Array, in dem die Knoten in dieser Reihenfolge abgelegt werden.

Page 43: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

43

Zweite Phase:

2. Ausgabe des Heaps: n-mal das Maximum (in der Wurzel) herausnehmen

(deletemax) und mit dem Element an der letzten Stelle des aktuellen

Heaps vertauschen. Heap wird um ein Element kürzer und geordnete Teilfolge am Ende des Array wird um ein

Element länger. Aufwand: O(n log n).

Page 44: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

44

Erste Phase:

1. Aufbau des Heaps:

Einfache Methode: n-mal insert

Aufwand: O(n log n).

Verbesserung: betrachte Array a[1 … n ] bereits als linksvollständigen Binärbaum und lass die Elemente in der Reihenfolge

a[n div 2] … a[2] a[1] einsinken!

(Die Elemente a[n] … a[n div 2 +1] sind schon in Blättern.)

Page 45: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

45

Formal: Teilheap:Ein Teilarray a[ i..k ] ( 1 i k <=n ) heißt

Teilheap, wenn gilt:

        für alle j aus {i,...,k} ist    

m(a[ j ]) m(a[ 2j ])     falls 2j k und  

m(a[ j ]) m(a[ 2j+1])  falls 2j+1 k

Ist a[i+1..n] bereits ein Teilheap, so wird durch Einsinkenlassen des Elements a[i] auch a[i…n] zu einen Teilheap.

Page 46: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

46

Aufwandsberechnung

Sei k = [log n+1]+ - 1.

Aufwand:

Für ein Element in der Ebene j von oben: k – j.

Insgesamt: {j=0,…,k} (k-j)•2j

= 2k • {i=0,…,k} i/2i =2 • 2k = O(n).

Page 47: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

47

Vorteil:

Neue Aufbaustrategie effizienter!

Anwendung: Wenn nur die m größten Elemente ausgegeben werden sollen:

1. Aufbau in O(n) Schritten.

2. Ausgabe der m größten Elemente in

O(m•log n) Schritten.

Gesamtaufwand: O( n + m•log n).

Page 48: Kapitel 6:  Suchbäume und weitere Sortierverfahren 6.1   Binäre Bäume

48

Nachtrag: Sortieren mit Suchbäumen

Algorithmus:1. Aufbau eines Suchbaums (z.B. AVL-Baums) aus der

zu sortierenden Folge durch Einfügeoperationen.2. Ausgabe in InOrder-Reihenfolge.

sortierte Folge.

Aufwand: 1. O(n log n) mit AVL-Bäumen, 2. O(n). Gesamt: O(n log n). Bis auf Konstanten optimal!