6 Halde (Heap)

Werbung
6
Halde (Heap)
Die Halde ist eine lineares Feld, welches die sogenannte Haldenbedinung erfüllt:
Haldenbedingung:
A[i]≥ max {A[2i], A[2i + 1]}, ∀i = 1, 2, . . .
n
2
.
Direkt aus der Denition ergibt sich, dass A[1] das Maximum des linearen Feldes
ist. Beispiel einer Halde:
Die Halde lässt sich auch als binärer Baum darstellen.
Mit den Funktionen LINKS(i) und RECHTS(i) kann auf den linken bzw. rechten Nachfolger des i-ten Elements in der Baumstruktur zugegrien werden, analog mit VATER(i) auf den Vorgänger.
LINKS (i)
1: RETURN 2i
RECHTS(i)
1: RETURN 2i + 1
VATER (i) 1: RETURN 2i
Wichtige Beobachtungen:
• Das Maximum sitzt in der Wurzel des Baums
• In jedem Knoten ist die Haldenbedingung erfüllt
• Die Maximale Tiefe des Baums ist blog nc
• In einem Teilbaum sind alle darunter liegenden Knoten kleiner oder ma-
ximal gleich groÿ.
1
In jedem Haldenbaum ist jedes Niveau bis auf das letzte voll (es gibt 2i Elemente der Höhe i), das letzte
Niveau enthält mindestens 1 Element. Für die Anzahl der Elemente in einem
Haldenbaum der Höhe h gilt also
Beweis für die Höhe des Haldenbaums:
n ≥ 1 + 2 + 4 + . . . + 2h−1 + 1 =
h−1
X
2i + 1 = (2h − 1) + 1 = 2h ,
i=1
Für die Höhe h gilt daher h ≤ bldnc (h ganzzahlig).
6.1
Verhalden (Heapify)
Verhalden ist der zentrale Prozess für alle Anwendungen der Haldenstruktur.
Mit n als Gröÿe der Halde (Die Länge des linaren Feldes).
VERHALDE (A,i)
1: l←LINKS(i), r←RECHTS(i)
2: index ← i
3: IF l≤n AND A[l]>A[i] THEN index←l
4: IF r≤n AND A[r]>A[index] THEN index←r
5: IF i6=index THEN
6:
VERTAUSCHE (A[i], A[index])
7:
VERHALDE (A,index)
: Der rekursive Aufruf erfolgt auf einem Teilbaum, der einen der beiden
Söhne von i als Wurzel hat. Dieser Teilbaum hat maximal halb so viele Elemente
wie der Teilbaum mit Wurzel i. Die Rekursiongleichung lautet daher T (n) ≤
O(1) + T ( n2 ). Die Lösung ist T (n) = O(log n):
Analyse
n
T (n) ≤ O(1) + T ( )
h 2
n i
≤ O(1) + O(1) + T ( )
4
n
= 2 · O(1) + T ( )
4
n
≤ 3 · O(1) + T ( )
8
n
≤ k · O(1) + T ( k )
2
= ldn · O(1) + O(1) = O(log n)
Diese Schranke folgt auch aus der Beobachtung, dass maximal die Höhe des
Haldenbaums, h ≤ bldnc, durchlaufen wird.
6.2
Aufbau einer Halde
Eine Halde kann aus einem beliebigen linearen Feld A aufgebaut werden:
2
BAUE_HALDE (A)
1: FOR i←n/2 DOWNTO 1
2:
VERHALDE (A,i)
: Das Verhalden wird n2 -mal durchgeführt. D.h. T (n) = O(n·log n).
Bei genauerer Betrachtung sieht man aber, dass eben nicht alle Elemente durch
die ganze Baumhöhe durch verhaldet werden müssen. Die Schranke O(n · log n)
ist nicht scharf.
Ein genauerer Ansatz ergibt sich aus der Beobachtung, dass es in einer Halde
n
mit n Elementen ≤ d 2h+1
e Elemente gibt, die mit Höhe h verhaldet werden
Pbldnc n
P
h
müssen: T (n) ≤ h=0 d 2h+1 eO(h) = O(n bldnc
) = O(n) .
h=0 2h P
h
(Die Summe kann durch eine unendliche Summe ∞
h=0 2h = 2 abgeschätzt
werden.)
Analyse
Damit kann eine Halde in linearer Zeit aus einem linearen Feld gebaut werden.
6.3
Sortieren mit Halden (Heap Sort)
Mit Hilfe des VERHALDE -Algorithmus kann man auch einen Sortieralgoritmus
konstruieren.
HEAP_SORT(A)
1: BAUE_HALDE(A)
2: FOR i ← n DOWNTO 2 DO
3:
VERTAUSCHE (A[1],A[i])
4:
n ← n-1
5:
VERHALDE (A,1)
Die Laufzeit von BAUE_HALDE ist O(n), die von VERHALDE O(log n). Die
Laufzeit beträgt daher T (n) = O(n) + (n − 1) · O(log n) = O(n log n). Der
Algorithmus arbeitet in-place.
6.4
Wartschlange (Priority Queue)
Eine weitere Anwendung dieser Datenstruktur ist die Warteschlange mit Prioritäten: Eine Warteschlange liegt vor, wenn folgende drei Operationen durchgeführt werden können:
• EINFUEGEN (A,x)
• MAX (A)
• ENTFERNE_MAX (A)
Die Funktionen mit Hilfe einer Halde umgesetzt in Pseudocode:
MAXIMUM (A)
1: RETURN A[1]
3
ENTFERNE_MAX (A)
1: A[1] ← A[n]
2: n ← n-1
3: VERHALDE (A,1)
EINFUEGEN (A,x)
1: n←n+1 , A[n]←x , i←n
2: WHILE i>1 AND A[i]>A[VATER(i)] DO
3:
VERTAUSCHE (A[i],A[VATER(i)])
4:
i←Vater(i)
Die Laufzeiten betragen für MAXIMUM, ENTFERNE_MAX und EINFUEGEN respektiv O(1), O(log n) und O(log n).
Mittels Einfügen kann eine Halde natürlich auch aufgebaut werden. Diese
Variante ist jedoch inezient.
BAUE_HALDE_LANGSAM(A)
1: N ← 1
2: FOR i=2 TO n DO
3:
EINFUEGEN (A,A[i])
Die Laufzeit beträgt
n
X
T (n) = O
!
= O(n log n).
ldi
i=2
|
{z
}
<(n−1)·ldn
Diese asymptotische Schranke ist schon scharf, da
n
X
i=2
ldi >
n
X
i= n
2
ldi >
n n
n
n
ld = ldn − = Ω(n log n).
2 2
2
2
Die Laufzeit ist also mit T (n) = Θ(n log n) deutlich langsamer als BAUE_HALDE,
das eine Halde in linearer Zeit bilden kann.
4
Herunterladen