1 Folie/Seite - Chair 11: ALGORITHM ENGINEERING

Werbung
Kap. 3: Sortieren (3)
Professor Dr. Petra Mutzel
Lehrstuhl für Algorithm Engineering, LS11
Fakultät für Informatik, TU Dortmund
6. VO
DAP2
SS 2009
Petra Mutzel
30. April 2009
DAP2 SS09
1
Überblick
•  Quick-Sort
•  Analyse von Quick-Sort
•  Quick-Sort Varianten
•  Heap-Sort
Petra Mutzel
DAP2 SS09
2
Termine für Übungstests
•  1. Übungstest:
•  Di 19. Mai, in der Vorlesung im
AudiMax, Beginn: ab 12:15 Uhr, ab 12
Uhr anwesend sein wegen Sitzordnung
•  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
3
Motivation
„Warum soll ich hier bleiben?“
Wir lernen Quick-Sort
„Was ist daran denn besonders?“
Quick-Sort gehört zu den „Top 10“
wichtigsten Algorithmen
Petra Mutzel
DAP2 SS09
4
Analyse von QuickSort: Average
•  Grundannahmen
–  alle Schlüssel sind verschieden
–  o.B.d.A. A[i]∈{1,2,…n}
–  alle
Permutationen
sind
gleich
wahrscheinlich
•  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
Petra Mutzel
DAP2 SS09
5
Analyse von QuickSort: Average
•  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.
Rekursionsgleichung der Laufzeitfunktionen:
wobei die Summe über alle n möglichen Aufteilungen
läuft und bn der Aufteilungsaufwand für eine Folge
der Länge n ist.
Petra Mutzel
DAP2 SS09
6
Analyse von QuickSort: Average
Einsetzen von T(0)=0:
Lösung der Rekursionsgleichung:
T(n)=Θ(n log n)
Petra Mutzel
DAP2 SS09
7
Beweis von Average-Case
•  Wir zeigen: T(n)=O(n log n)
•  T(n)=Ω(n log n) ähnlich (o.Bw.)
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
8
Beweis von Average-Case ff
Induktionsschluss: Sei nun n≥3, Beh. gilt für alle
kleineren Werte:
Diese Ungleichung gilt, falls c≥4b
Wähle insgesamt c=max {a/2+b,4b}
Eigenschaften von QuickSort
•  Anzahl der Schlüsselvergleiche:
Cbest(n)=Cavg(n)=Θ(n log n); Cworst(n)=Θ(n2)
•  Eigenschaften:
–  in situ?
Θ(n) zusätzlichen Speicher
–  adaptiv?
–  stabil?
•  sehr gut in der Praxis
•  es existieren viele Varianten
Quicksort - Varianten
•  Randomisierter Quicksort
•  Quicksort mit log(n) Speicher
Petra Mutzel
DAP2 SS09
11
Randomisierter Quick-Sort
Ziel: Laufzeit unabhängig von der „Qualität“ der
Eingabefolge (vorsortiert, etc…)
Idee: Wähle Pivotelement zufällig aus!
Einfachste Umsetzung: „Neues“ Partitionieren:
(1) z := Zufallszahl zwischen l und r
(2) vertausche A[z] mit A[r]
(3) normales Partitionieren
Petra Mutzel
DAP2 SS09
12
Randomisierter Quick-Sort
Randomisierte Algorithmen: Es lassen sich
keine Best-Case und Worst-Case Beispiele
mehr konstruieren!
Aber: Natürlich kann der Worst-Case noch
eintreten!
Man berechnet eine Erwartete Laufzeit
= Erwartungswert der Laufzeit ≈
durchschnittliche Laufzeit  Average-Case
E[ T(n) ] = O(n log n)
Petra Mutzel
DAP2 SS09
13
Quick-Sort mit log(n) Speicher
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) Petra Mutzel
DAP2 SS09
14
Quick-Sort mit log(n) Speicher
Idee: Lange Teile sofort bearbeiten
bisher
Zwischenschritt
(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)  }
(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
15
Quick-Sort mit log(n) Speicher
l ... p-1 p
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
Was bisher geschah…
Insertion-Sort: O(n2)
einfach
Selection-Sort: Θ(n2)
Merge-Sort: O(n log n)
nicht in-situ
Quick-Sort: praxis schnell
O(n2)
Jetzt:
Heap-Sort:
O(n log n) , in-situ
Auf Basis von Selection-Sort!
Petra Mutzel
DAP2 SS09
17
Übersicht
Heap-Sort
Einführung in Datenstruktur Heap
Analyse von Heap-Sort
Petra Mutzel
DAP2 SS09
18
Selection-Sort…
GUT
In jedem Schritt wird ein Schlüssel an seine
richtige Position gesetzt
SCHLECHT
Suchen des richtigen Schlüssels: Θ(n)
IDEE
Den unsortierten Teil „vorsortieren” 
Schnelles Finden des nächsten Schlüssels
Petra Mutzel
DAP2 SS09
19
Heap (=Haufen)
Heap: eine neue Datenstruktur!
Speicherung…
…weiterhin als Array (in-situ!)
Interpretation…
…als binärer Baum,
an dessen Wurzel immer das größte
Element stehen soll
Petra Mutzel
DAP2 SS09
20
Definition Heap
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:
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
21
Heap: Interpretation
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
2
8
6
3
7
4
3
8
5
4
6
5
7
2
1
Petra Mutzel
DAP2 SS09
22
Heap: Interpretation
1
S
Interpretation als Binärer Baum
2
4
T
1
Speicherung als Array
O
3
5
I
2
3
6
4
S O R T
R
N
5
7
6
G
7
I N G
Binärer Baum
Wurzel
Ebene 1
Ebene 2
Knoten
1
2
S
O
3
Elter / Vater
R
Kind
= Einträge im Baum
Ebene 3 4 T
Kanten
verbinden Knoten
5
I
6
N
7
G
Blätter = Knoten ohne Kinder
Binärer Baum: maximal 2 Kinder pro Knoten
Tiefe/Höhe des Baums
1
Ebene 1
2
Ebene 2
4
Ebene 3 4 T
15
8
Ebene 4
2k-1
2k-1
Ebene k
3
7
# Knoten PRO Ebene
# Knoten BIS Ebene
1
1
2
S
O
5
3
I
6
N
R
7
G
Tiefe/Höhe des Baums
3
# Knoten PRO Ebene
# Knoten BIS Ebene
1
1
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
G
n = 2h  hmax = log2 n
7
 Höhe des Heaps: O(log n) 
Heap-Eigenschaft
Heap–Eigenschaft:
Schlüssel der
Elternknoten ist größer
gleich denen seiner
Kinder
1
2
S
O
3
R
Array A[1…n]
∀  Indizes i:
A[i] ≥ A[2i] und
A[i] ≥ A[2i+1]
falls diese Indizes
existieren
4
T
5
I
6
N
7
G
nicht erfüllt!
1
2
3
4
S O R T
5
6
7
I N G
Idee von Heap-Sort
Elemente im unsortierten Array so verschieben,
dass die Heap-Eigenschaft erfüllt ist
(CreateHeap)
Größtes Element im Heap finden ist einfach
 Wurzel = erstes Element im Array
Wurzel aus Heap entfernen
 Heap-Eigenschaften wiederherstellen
(Sifting)
Petra Mutzel
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
4
T
1
S
O
3
5
I
2
3
6
4
S O R T
Petra Mutzel
R
N
5
7
6
G
7
I N G
DAP2 SS09
30
CreateHeap
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
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

N
7
2i
5
G
2i+1
6
7
I N G
CreateHeap
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
1
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
} }
CreateHeap
Heap-Erstellung beendet
i
procedure CREATEHEAP () {
for i := n/2 … 1 {
SIFTDOWN (i, n)
} }
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
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
G
T
S
3
O
5
I
1
2
3
6
4
R
N
5
7
6
k
G
T
7
G
T S R O I N G
T
Petra Mutzel
DAP2 SS09
34
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
G
S
O
G
S
3
G
O
5
I
1
2
3
6
4
R
N
5
7
6
k
T
7
G
S O
G
S R G
O I N T
Petra Mutzel
DAP2 SS09
35
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
N
R
S
O
3
G
5
I
1
2
3
6
4
R
N
k
N
S
5
7
6
T
7
N
R
S O N
R G I N
S T
Petra Mutzel
DAP2 SS09
36
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
O
RI
O
I
3
G
5
k
RI
1
2
3
6
4
N
S
5
7
6
T
7
O
RI O
I N G RI S T
Petra Mutzel
DAP2 SS09
37
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
2
4
O
G
N
I
3
k
O
G
5
R
1
2
3
6
4
G
N
S
5
7
6
T
7
O
G
N I G
N O
G R S T
Petra Mutzel
DAP2 SS09
38
HeapSort
procedure HEAPSORT () {
CREATEHEAP ()
for k := n … 2 {
vertausche A[1] und A[k]
SIFTDOWN (1, k-1)
} }
1
4
2
G
I
O
5
R
1
2
3
G
NI
3
6
4
k
G
N
S
5
7
6
T
7
G
NI G
I G
N O R S T
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
Herunterladen