Überblick
Kap. 3: Sortieren (3)
• Quick-Sort
• Analyse von Quick-Sort
• Quick-Sort Varianten
Professor Dr. Petra Mutzel
Lehrstuhl für Algorithm Engineering, LS11
Fakultät für Informatik, TU Dortmund
6. VO
DAP2
SS 2009
Petra Mutzel
• Heap-Sort
30. April 2009
DAP2 SS09
1
Petra Mutzel
DAP2 SS09
Termine für Übungstests
Motivation
• 1. Übungstest:
• Di 19. Mai, in der Vorlesung im
AudiMax, Beginn: ab 12:15 Uhr, ab 12
Uhr anwesend sein wegen Sitzordnung
„Warum soll ich hier bleiben?“
Wir lernen Quick-Sort
„Was ist daran denn besonders?“
• 2. Übungstest:
• Di 16. Juni, in der VO im AudiMax,
Beginn: ab 12:15 Uhr, ab 12 Uhr
anwesend sein wegen Sitzordnung
Petra Mutzel
DAP2 SS09
Quick-Sort gehört zu den „Top 10“
wichtigsten Algorithmen
3
Analyse von QuickSort: Average
DAP2 SS09
4
• Teilt man sämtliche Folgen mit n Elementen mit dem
Pivotelement (an der letzten Stelle), so erhält man
sämtliche Folgen der Länge k-1 und n-k.
– alle Schlüssel sind verschieden
– o.B.d.A. A[i]∈{1,2,…n}
– alle
Permutationen
sind
gleich
wahrscheinlich
Rekursionsgleichung der Laufzeitfunktionen:
• Jede Zahl k∈{1,2,…,n} tritt mit gleicher
Wahrscheinlichkeit 1/n an Position n auf
• Pivotelement k erzeugt zwei Folgen der Längen k-1
und n-k
• Diese Folgen sind wieder zufällig:
gilt
DAP2 SS09
Petra Mutzel
Analyse von QuickSort: Average
• Grundannahmen
Petra Mutzel
2
wobei die Summe über alle n möglichen Aufteilungen
läuft und bn der Aufteilungsaufwand für eine Folge
der Länge n ist.
5
Petra Mutzel
DAP2 SS09
6
1
Analyse von QuickSort: Average
Beweis von Average-Case
Einsetzen von T(0)=0:
• Wir zeigen: T(n)=O(n log n)
• T(n)=Ω(n log n) ähnlich (o.Bw.)
Lösung der Rekursionsgleichung:
T(n)=Θ(n log n)
Wir zeigen durch vollständige Induktion:
es existieren c,n0>0, so dass für alle n≥n0:
T(n) ≤ cn log n
Wir wählen: n0=2.
Induktionsanfang: n=2: T(2)=T(1)+bn=a+2b
somit ist T(2)≤c2 log 2 g.d.w. c≥(a+2b)/2=a/2+b
Petra Mutzel
DAP2 SS09
7
Beweis von Average-Case ff
Petra Mutzel
DAP2 SS09
8
Eigenschaften von QuickSort
Induktionsschluss: Sei nun n≥3, Beh. gilt für alle
kleineren Werte:
• Anzahl der Schlüsselvergleiche:
Cbest(n)=Cavg(n)=Θ(n log n); Cworst(n)=Θ(n2)
• Eigenschaften:
– in situ?
Θ(n) zusätzlichen Speicher
– adaptiv?
– stabil?
Diese Ungleichung gilt, falls c≥4b
Wähle insgesamt c=max {a/2+b,4b}
Quicksort - Varianten
• sehr gut in der Praxis
• es existieren viele Varianten
Randomisierter Quick-Sort
Ziel: Laufzeit unabhängig von der „Qualität“ der
Eingabefolge (vorsortiert, etc…)
• Randomisierter Quicksort
Idee: Wähle Pivotelement zufällig aus!
• Quicksort mit log(n) Speicher
Petra Mutzel
Einfachste Umsetzung: „Neues“ Partitionieren:
(1) z := Zufallszahl zwischen l und r
(2) vertausche A[z] mit A[r]
(3) normales Partitionieren
DAP2 SS09
11
Petra Mutzel
DAP2 SS09
12
2
Randomisierter Quick-Sort
Quick-Sort mit log(n) Speicher
Randomisierte Algorithmen: Es lassen sich
keine Best-Case und Worst-Case Beispiele
mehr konstruieren!
Aber: Natürlich kann der Worst-Case noch
eintreten!
Bisher: O(n) Speicher
l ... p-1 p
p+1................ r
Idee: Lange Teile sofort bearbeiten
D.h.: Rekursiver Aufruf nur für kleinere Teile.
diese Teile sind ≤ Hälfte der betrachteten Länge
Tiefe der rekursiven Aufrufe: O(log n) Man berechnet eine Erwartete Laufzeit
= Erwartungswert der Laufzeit ≈
durchschnittliche Laufzeit Average-Case
E[ T(n) ] = O(n log n)
Petra Mutzel
DAP2 SS09
13
Petra Mutzel
l ... p-1 p
Idee: Lange Teile sofort bearbeiten
bisher
Zwischenschritt
(1) procedure QS(ref A,l,r)
(2) while l < r do {
(3) p := Partition(A,l,r)
(4) QuickSort(A,l,p-1)
(5) l := p+1
(6) }
Petra Mutzel
DAP2 SS09
14
Quick-Sort mit log(n) Speicher
Quick-Sort mit log(n) Speicher
(1) procedure QS(ref A,l,r)
(2) if l < r then {
(3) p := Partition(A,l,r)
(4) QuickSort(A,l,p-1)
(5) QuickSort(A,p+1,r)
(6) }
DAP2 SS09
15
Was bisher geschah…
Zwischenschritt
(1) procedure QS(ref A,l,r)
(2) while l < r do {
(3)
p := Partition(A,l,r)
(4)
QuickSort(A,l,p-1)
(5)
l := p+1
(6) }
p+1................ r
(1) procedure QS(ref A,l,r)
(2) while l < r do {
(3)
p := Partition(A,l,r)
(4)
if p-l < r-p then {
(5)
QuickSort(A,l,p-1)
(6)
l := p+1
(7) } else {
(8)
QuickSort(A,p+1,r)
(9)
r := p-1
(10) } } Petra Mutzel
DAP2 SS09
16
Übersicht
Insertion-Sort: O(n2)
einfach
2
Selection-Sort: Θ(n )
Merge-Sort: O(n log n)
nicht in-situ
Quick-Sort: praxis schnell
O(n2)
Heap-Sort
Einführung in Datenstruktur Heap
Analyse von Heap-Sort
Jetzt:
Heap-Sort:
O(n log n) , in-situ
Auf Basis von Selection-Sort!
Petra Mutzel
DAP2 SS09
17
Petra Mutzel
DAP2 SS09
18
3
Selection-Sort…
Heap (=Haufen)
GUT
In jedem Schritt wird ein Schlüssel an seine
richtige Position gesetzt
Heap: eine neue Datenstruktur!
Speicherung…
SCHLECHT
…weiterhin als Array (in-situ!)
Suchen des richtigen Schlüssels: Θ(n)
Interpretation…
IDEE
Den unsortierten Teil „vorsortieren”
Schnelles Finden des nächsten Schlüssels
Petra Mutzel
…als binärer Baum,
an dessen Wurzel immer das größte
Element stehen soll
DAP2 SS09
19
Petra Mutzel
Definition Heap
12345678
F=<8,6,7,3,4,5,2,1>
Ähnlich sind Min-Heaps definiert. Dort gilt:
Falls 2i≤n, so gilt ki≤k2i und falls 2i+1≤n so gilt ki≤k2i+1.
Petra Mutzel
DAP2 SS09
F=<8,6,7,3,4,5,2,1>
1
Heap-Eigenschaft:
Falls 2i≤n, so gilt ki≥k2i und
falls 2i+1≤n so gilt ki≥k2i+1.
Heap–Eigenschaft:
Schlüssel der
Elternknoten ist größer
gleich denen seiner
Kinder
21
Heap: Interpretation
2
6
3
3
8
5
4
7
6
5
7
2
1
Petra Mutzel
S
8
4
Binärer Baum
1
20
Heap: Interpretation
Eine Folge H=<k1,k2,…,kn> von Schlüsseln ist ein
(Max-) Heap, wenn für jede Position i die folgende
Heap-Eigenschaft erfüllt ist:
Falls 2i≤n, so gilt ki≥k2i und falls 2i+1≤n so gilt ki≥k2i+1.
Beispiel:
DAP2 SS09
DAP2 SS09
22
Wurzel
Ebene 1
1
S
Interpretation als Binärer Baum
2
O
3
Ebene 2
R
Knoten
2
O
3
Elter / Vater
R
Kind
= Einträge im Baum
4
T
5
I
6
N
7
G
Ebene 3 4 T
Kanten
verbinden Knoten
1
Speicherung als Array
2
3
4
S O R T
5
6
7
I N G
5
I
6
N
7
G
Blätter = Knoten ohne Kinder
Binärer Baum: maximal 2 Kinder pro Knoten
4
Tiefe/Höhe des Baums
Ebene 1
2
Ebene 2
1
2
4
Ebene 3 4 T
15
8
Ebene 4
2k-1
2k-1
Ebene k
7
S
1
O
5
3
I
6
R
N
7
G
Heap-Eigenschaft
Heap–Eigenschaft:
Schlüssel der
Elternknoten ist größer
gleich denen seiner
Kinder
1
2
Ebene 1
Tiefe/Höhe eines
1 S Baums =
Anzahl der Ebenen - 1
2
Ebene 2
Gegebene
Höhe h: 3 R
2 O
nmax = 2h+1-1
nmin = 2h
4
Maximale Höhe bei n
Ebene 3 4Elementen?
6 N
T 5 I
15
8
Ebene 4
2k-1
2k-1
Ebene k
7
7 G
n = 2h hmax = log2 n
Höhe des Heaps: O(log n)
Elemente im unsortierten Array so verschieben,
dass die Heap-Eigenschaft erfüllt ist
(CreateHeap)
S
O
3
R
Größtes Element im Heap finden ist einfach
Wurzel = erstes Element im Array
∀ Indizes i:
4
T
5
I
6
N
7
G
Wurzel aus Heap entfernen
Heap-Eigenschaften wiederherstellen
(Sifting)
nicht erfüllt!
falls diese Indizes
existieren
1
2
3
4
S O R T
5
6
7
I N G
Petra Mutzel
CreateHeap
DAP2 SS09
29
CreateHeap
Beobachtung
Die Heapbedingung ist
an den Blättern erfüllt.
1
2
Algorithmus
Betrachte Knoten über den
Blättern repariere
Teilheap
Bearbeite Baum von unten
nach oben Teilbäume
sind immer Heaps
1
Idee von Heap-Sort
Array A[1…n]
A[i] ≥ A[2i] und
A[i] ≥ A[2i+1]
3
# Knoten PRO Ebene
1
# Knoten BIS Ebene
3
# Knoten PRO Ebene
# Knoten BIS Ebene
1
Tiefe/Höhe des Baums
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
S
O
3
R
1
S
i
2 O
procedure SIFTDOWN (i, m) {
while Knoten i hat Kinder ≤ m
{
j := Kind ≤ m mit größerem
Wert
5 I
6
4 T
if A[i] < A[j] then {
vertausche A[i] und A[j]
1
2
3
4
i := j
S
O
R
T
} else return
} }
3
R
4
T
1
5
I
2
3
6
4
S O R T
Petra Mutzel
N
5
7
6
G
7
I N G
DAP2 SS09
30
N
7
2i
5
G
2i+1
6
7
I N G
5
CreateHeap
CreateHeap
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
1
Heap-Erstellung beendet
i
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
S
i
2 O
procedure SIFTDOWN (i, m) {
3 R
while Knoten i hat Kinder ≤ m
{
j := Kind ≤ m mit größerem
Wert
5 I
6 N
7 G
4 T
if A[i] < A[j] then {
2i
2i+1
vertausche A[i] und A[j]
1
2
3
4
5
6
7
i := j
S O R T I N G
} else return
} }
1
S
j
2 T
procedure SIFTDOWN (i, m) {
3 R
while Knoten i hat Kinder ≤ m
{
j := Kind ≤ m mit größerem
Wert
5 I
6 N
7 G
4 O
if A[i] < A[j] then {
vertausche A[i] und A[j]
1
2
3
4
5
6
7
i := j
S T R O I N G
} else return
} }
HeapSort
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
S
3
O
5
I
1
2
3
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
G
T
6
4
R
N
5
7
6
k
G
T
1
4
7
G
T S R O I N G
T
Petra Mutzel
DAP2 SS09
2
O
G
S
G
O
5
I
1
2
3
G
S
3
6
4
R
N
5
7
6
k
T
7
G
S O
G
S R G
O I N T
34
HeapSort
Petra Mutzel
DAP2 SS09
35
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
4
2
O
G
5
I
1
2
3
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
N
R
S
3
6
4
R
N
k
N
S
5
7
6
T
4
7
N
R
S O N
R G I N
S T
Petra Mutzel
DAP2 SS09
1
2
O
I
G
5
k
RI
1
2
3
O
R
I
3
6
4
N
S
5
7
6
T
7
O
R
I O
I N G R
I S T
36
Petra Mutzel
DAP2 SS09
37
6
HeapSort
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
I
3
k
O
G
5
R
1
2
3
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
O
G
N
6
4
G
N
S
5
7
6
T
4
7
O
G
N I G
N O
G R S T
Petra Mutzel
DAP2 SS09
1
2
G
I
O
5
R
1
2
3
G
N
I
3
6
4
k
G
N
S
5
7
6
T
7
G
N
I G
I G
N O R S T
38
Petra Mutzel
DAP2 SS09
39
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
4
2
k
G
I
O
5
R
1
2
3
G
I
3
6
4
N
S
5
7
6
T
7
G
I G
I N O R S T
Petra Mutzel
DAP2 SS09
40
7