mm6: more sorting algorithms: heap sort and quick sort...
TRANSCRIPT
1
Algorithms and Architectures IRasmus Løvenstein Olsen (RLO) , Jimmy Jessen Nielsen (JJE)
Mm6: More sorting algorithms: Heap sort and quick sort - October 29, 2008
2
1. Introduction to analysis and design of algorithms(RLO)2. Recursive algorithms and recurrences (RLO)3. More about recurrences (RLO)4. Greedy algorithms, backtracking and more recurrences(RLO)5. Counting, probabilities and randomized algorithms (RLO)6. More sorting algorithms: Heap sort and quick sort (RLO)7. A little bit more about sorting - and more times for exercises (RLO)8. Hash tables, Hashing and binary search trees (RLO)9. Binary search trees, red-black trees (JJE)10. Red-black trees continued + string matching (JJE)
Algorithms and Architectures II
3
Dagsorden
• Heap sort• Hvad er en heap?• Basale heap operationer• Vedligeholdelse af heap egenskabet under sortering• Gennemgang af heap sort via eksempel• Anvendelse af heap sort: Prioritetskøer
• Quick sort• Virkemåde• Partitionering af array• Ydelse af quick sort• Effektivisering vha. randomiseret input
• Opsummering og konklusion• Opgaver
4
Sortering af data
• Sortering af data sker mange steder• Data baser• Regneark• Videnskabelig analyse af måle data• …
• Flere eksempler på sorteringsalgoritmer• Heap sort
• Organisering af data i såkaldte heaps
• Quick sort• Re-arrangering af data efter valgt pivot punkt
• Counting sort• Baserer sig på antal af specifikke elementer og udnytter specifik viden om data
• Bucket sort• Re-organisering af data i ”buckets”
5
Hvad er en heap?
• En (binær) heap er en data struktur der kan karakteriseres som et array med et næsten komplet binært træ
• Et array A der representerer sådan en strukturindeholder• Længde : length[A]• Heap størrelse : heap-size[A]• heap-size[A] ≤ length[A]
• Grafisk representation
A
B C
D E
A B C D E
6
Heap specifikke operationer
• Parent(i)• Return(i/2)
• Left(i)• Return 2i
• Right(i)• Return 2i+1
1
2 3
4 5 6 7
8 9 10
7
Max-heap og min-heap• Max-heap egenskab
• A[parent(i)] ≥ A[i]Det største element er root elementet, og alle under elementer har værdier mindre end elemente selv
• Min-heap egenskab• A[parent(i)] ≤ A[i]
Det mindste element er root elementet, og alle under elementer har værdier større end elementet selv
• Egenskaberne bliver udnyttet i forskellige sammenhæng, f.eks. Prioritetskøer og sorteringsalgoritmer
• Vi ser på heapsort der udnytter disse egenskaber og kigger på flg. Procedurer• Max-heapify: Sikrer vores heap egenskaber bibeholdes, T(n) = O(log(n))• Build-max-heapify: Producerer en max-heap fra et usorteret input, T(n) = O(n)• Heapsort algoritme: Sorterer arrayet, T(n) = O(nLog(n))
8
Vedligeholdelse af heap egenskab – MAX-HEAPIFY
• Input til algoritme: et array A og et indeks i til arrayet
• Vi antager de binære træer, med rod i Left[i] og Right[i] er max-heaps
• A[i] er derimod muligvis mindre end dens undergrene
MAX-HEAPIFY (A, i)
1 L = Left(i) 6 If R ≤ heap-size[A] and A[r]>A[largest]
2 R = Right(i) 7 then largest = R
3 If L≤heap-size(A) and A[L] > A[i] 8 If largest ≠ i
4 then largets = L 9 then exchange A[i] with A[largest]
5 else largest = i 10 MAX-HEAPIFY(A, largest)
9
Eksempel med Max-heapify
• Heap-size[A] = 10
• Initial værdi af A• A[2] = 4 bryder max-heap egenskabet
idet den ikke er større end dens to undergrene
• Vi skal have flyttet den således vi genskaber/ opnår max-heap egenskab
16
4 10
14 7 9 3
2 8 1
1
2 3
4 5 6 7
8 9 10
10
Eksempel med Max-heapify #2
Ved udskiftning med A[4] opnår vi:• Genoprettelse/opnåelse af max-
heap egenskab for node 2• Vi har nu A[4] = 4 > A[9]• Ødelæggelse af max-heap
egenskab for node 4• Vi skal have flyttet mere rundt på
tingene
16
14 10
4 7 9 3
2 8 1
1
2 3
4 5 6 7
8 9 10
11
Eksempel med Max-heapify #3
Ved rekursivt kald til max-heapifyopnår vi:
• A[9] = 4, A[4] = 8• Dermed har vi opnået et max-heap
egenskab for det binære træ
16
14 10
8 7 9 3
2 4 1
1
2 3
4 5 6 7
8 9 10
12
Max-heapify algoritme kompleksitet
• Eksekveringstiden for max-heapify algoritmen er flg.• Θ(1) for at genoprette forholdet mellem A[i], A[Left(i)] og A[Right(i)]
plus tiden for at udføre max-heapify på en af de underliggende knudepunkter• De enkelte undergrene har hver maksimalt 2n/3 elementer
værste tilfælde når den sidste række er fyldt helt op (hvorfor det er 2n/3 er en af dagens opgaver☺)
• Dermed er rekursiviteten givet ved
• Den har vi set før... Og giver T(n) = O(log2(n))
)1()3/2()( Θ+≤ nTnT
13
Konstruering af en heap
• Vi kan nu benytte os af Max-Heapify til at konvetere et array A[1..n] til en max-heap
Build-Max-Heap (A)
1 Heap-size[A] = length[A]
2 For i = length[A]/2 downto 1
3 do Max-Heapify (A,i)
14
Hvordan Build-Max-heap virker - grafisk
4
1 3
2 16 9 10
14 8 7
1
2 3
4 5 6 7
8 9 10
4 1 3 216 9
10
14 8 7
4
1 3
2 16 9 10
14 8 7
1
2 3
4 5 6 7
8 9 10
15
Hvordan Build-Max-heap virker – grafisk #2
4
1 3
14 16 9 10
2 8 7
1
2 3
4 5 6 7
8 9 104
1 10
14 16 9 3
2 8 7
1
2 3
4 5 6 7
8 9 10
16
Hvordan Build-Max-heap virker – grafisk #3
4
16 10
14 7 9 3
2 8 1
1
2 3
4 5 6 7
8 9 1016
14 10
8 7 9 3
2 4 1
1
2 3
4 5 6 7
8 9 10
17
Bevis for korrekthed af Build-Max-Heap
• Loop invariant defineres som• Ved begyndelsen af hver iteration af For loopet i linie 2-3,
er knudepunkterne i+1, i+2, ... N roden af en max-heap
• Initialisering af algoritmen:• Pga. konstruktionen af en heap bliver elementerne n/2 + 1, n/2 +2, ... , n automatisk
klassificeret som endepunkter i træet. Det er det samme som de er rod for et 1-element stort max-heap. Derfor holder loop invarianten under initialisering af algoritmen.
1
2 3
4 5 6 7
8 9 101 2 3 4 5 6 7 8 9
10
18
Bevis for korrekthed af Build-Max-Heap #2
• Vedligeholdelse af algoritmen• Bemærk at
• Undergrenen af den i’te knude, er altid nummereret højere end i• Undergrenen af den i’te knude er altid en rod i en max-heap!
• Ved start af loop (markeret med blå) er max-heap egenskab opretholdt for undergrene
• Ved udløb, er det samme gældende nu også fra i4
1 10
14
16
9 3
2 8 7
1
2 3
4 5 6 7
8 9 10
(1) (2)
4
1 3
2 16
9 10
14
8 7
1
2 3
4 5 6 7
8 9 10
19
Bevis for korrekthed af Build-Max-Heap #3
• Terminering: Når i = 0 skal samtlige knudepunkter iflg. Loop invariantenvære rod for et max-heap
16
14 10
8 7 9 3
2 4 1
1
2 3
4 5 6 7
8 9 10
20
Udførselstid for Build-Max-heap
• Som sagt, udførslen af max-heapify er O(log2(n))
• Max-heapify bliver kaldt O(n) gange, og dermed får vi en øvre grænse for vores kompleksitet på O(nLog2(n))
• Men, vi kan gøre det bedre!
• En n-element heap har højden h = Log2(n) og allerhøst n/2h+1 knuder
• Tiden for max-heapify kan også skrives som O(h), og så kan vi skrive den samlede tidsmæssige pris for udførslen af algoritmen (på tavlen)
• Dermed har vi en kompleksitet på O(n) (men den falder selvfølgelig ogsåunder O(nLog2(n)).
21
Heap sort algoritmen! Endelig…
• Pudsigt nok bygger heap sort på• Build-Max-Heap• Max-Heapify
• Algoritmen baserer sig påudskiftning mellem øversteog nederste element og derefter re-etablering afheap egenskabet
• Heap sort er en meget anvendt algoritme, bl.a. til prioritets køer som vi ser nærmeret på lidt senere
Max-Heapify (A, 1)5
heap-size[A] = heap-size[A] – 14
Heap-sort(A)
1 Build-max-heap(A)
2 For i = length(A) downto 2
3 do exchange A[1] = A[i]
22
Heap sort – grafisk gennemgang
16
14 10
8 7 9 3
2 4 1
1
2 3
4 5 6 7
8 9 10 14
8 10
4 7 9 3
2 1 16
1
2 3
4 5 6 7
8 9 10
Udgangspunkt efter Build-Max-Heapify
16
14
10 8 7 9 3 2 4 1
23
Heap sort – grafisk gennemgang
10
8 9
4 7 1 3
2 14 16
1
2 3
4 5 6 7
8 9 10 9
8 3
4 7 1 2
10 14 16
1
2 3
4 5 6 7
8 9 10
24
Heap sort – grafisk gennemgang
18
7 3
4 2 1 9
10 14 16
2 3
4 5 6 7
8 9 10 7
4 3
1 2 8 9
10 14 16
2 3
4 5 6 7
8 9 10
25
Heap sort – grafisk gennemgang1
4
2 3
1 7 8 9
10 14 16
2 3
4 5 6 7
8 9 10
13
2 1
4 7 8 9
10 14 16
2 3
4 5 6 7
8 9 10
26
Heap sort – grafisk gennemgang1
2
1 3
4 7 8 9
10 14 16
2 3
4 5 6 7
8 9 10
11
2 3
4 7 8 9
10 14 16
2 3
4 5 6 7
8 9 101 2 3 4 7 8 9
10
14
16
27
Heap sort - køretid• Heap sort proceduren tager O(nLog(n))
• Build-Max-Heap(n) = O(n)• Max-Heapify(n) = O(Log(n)) (kaldes n-1 gange)
• Sammenlign med Quicksort der tager O(n2)• Der dog i gennemsnit, O(nLog(n)), har en bedre tid end heap sort
• Og med merge-sort Θ(nLog(n))• Der dog kræver Ω(n) lager plads mod O(1) lager plads for heap sort
• En hybrid af quicksort og heap sort blev udviklet i 1997• Algoritmen starter med quick sort og ved en hvis størrelse af
rekursivitetsdybden skifter den til heap sort• Algoritmen udnytter dermed de bedste egenskaber af heap sort og
quick sort
28
Eksempel på anvendelse: Prioritets køer• En prioritetskø er en datastruktur til vedligeholdelse af et sæt af
elementer, hver med en tilknyttet værdi kaldet en nøgle
• Prioritetskøer anvendes bl.a.• Planlægning af jobs i et operativ system• Håndtering af data trafik• Diskrete event simulatorer• Effektiv søgning af korteste sti i en vægtet graf, f.eks. A* algoritmen.
Prioritetskøen indeholder, efter prioritet, lovende løsninger der skal efterprøves.
• …. 16
14 10
8 7 9 3
2 4 1
1
2 3
4 5 6 7
8 9 10
29
Hvorfor anvende heaps for prioritets køer?
* værste gennemsnitstid
O(1)O(m log(n+m))O(m log(n+m))O(1)Merge
O(log n)*O(log n)O(n)O(n)Delete
O(1)*O(log n)O(log n)O(1)Decreasekey
O(log n)*O(log n)O(log n)O(n)Deletemin
O(1)O(1)O(1)O(n)Accessmin
O(1)O(log n)O(log n)O(1)Insert
FibonacciHeap(Min-)HeapBinary TreeLinked List
30
Dagsorden
• Heap sort• Hvad er en heap?• Basale heap operationer• Vedligeholdelse af heap egenskabet under sortering• Gennemgang af heap sort via eksempel• Anvendelse af heap sort: Prioritetskøer
• Quick sort• Virkemåde• Partitionering af array• Ydelse af quick sort• Effektivisering vha. randomiseret input
• Opsummering og konklusion• Opgaver
31
Quick sort
• Del-og-hersk type sorteringsalgoritme
• Del: Opdel arrayet A[p..r] i to del-arrays (potentielt tomme) A1 = A[p..q-1] og A2 = A[q+1..r], således A1 ≤ A[q] ≤ A2Bemærk det er nødvendigt at finde q som en del af denne process
• Hersk: Sorter de to del-array ved et rekursivt kald til quicksort
• Kombiner: Eftersom de sorterede del-arrays er sorteret ved returnering, er kombinering nem: hele arrayet A = [A1 A2] er sorteret.
QUICKSORT (A, p, r)
1 If p < r
2 then q = Partition (A, p, r)
3 Quicksort(A, p, q – 1)
4 Quicksort(A, q + 1, r)
32
Partitionering af arrayet
• Nøglen i algoritmen ligger i at dele arrayet op på en smart måde
• Valg af et pivot punkt, x, hvormed databliver sorteret i de respektive områder
Return i + 18
exchange A[i+1] «» A[r]7
exchange A[i] «» A[j]6
then i = i +15
PARTITION (A, p, r)
1 x = A[r]
2 I = p – 1
3 For j = p to (r – 1)
4 do if A[j] ≤ x
x
≤ x > x ubegrænset
33
To tilfælde af iterationer
• Hvis A[j] > x
• Hvis A[j] ≤ X
>x x
≤ x > x
x
≤ x > x
≤ x x
≤ x > x
x
≤ x > x
34
Eksempel på partitionering af et array
2 8 7 1 3 5 6 4
2 8 7 1 3 5 6 4
2 8 7 1 3 5 6 4
2 8 7 1 3 5 6 4
2 1 7 8 3 5 6 4
2 1 3 8 7 5 6 4
2 1 3 8 7 5 6 4
2 1 3 8 7 5 6 4
2 1 3 4 7 5 6 8
35
Ydelsen af Quicksort
• Værste tilfælde• Sker når rutinen deler et problem op i et med hhv. n – 1 og 0 elementer• Antag dette sker i hvert rekursivt kald
• T(0) = Θ(1)• T(n) = T(n – 1) + T(0) + Θ(n) = T(n – 1) + Θ(n)• = Θ(n2)
• Bedste tilfælde • Bedste tilfælde sker når problemet deles op i maksimalt n/2 elementer• Antag dette sker i hver rekursivt kald
• T(n) ≤ 2T(n/2) + Θ(n)• = O(nLog2(n))
36
Gennemsnitsydelsen af quicksort
• Påstand: Gennemsnitsydelsen er tættere på bedste tilfælde, end på værste tilfælde
n
(1/10)n (9/10)n
(1/100)n (9/100)n (9/100)n (81/100)n
1
Log10/9(n)
cn
cn
cn
≤ cn
1
1
≤ cn
Log10(n)
O(nLog(n))
cnnTnTnT ++≤ )10/()10/9()(
37
Randomiseret version af quicksort
• Ydelsesanalysen er baseret på at alle permutationer af input muligheder sker med lige stor sandsynlighed
• I virkelighedens verden er dette oftest ikke tilfældet!• Modificering af partitioneringsalgoritmen til
• Ideen er at vælge pivot punktet x tilfældigt, i stedet for altid at vælge x = A[r] (det sidste element i input arrayet)
RANDOM-PARTITION (A, p, r)
1 i = Random(p, r)
2 Exchange A[r] with A[i]
3 Return Partition (A, p, r)
38
Ydelse for randomiseret quicksort
• For værste tilfælde
• I gennemsnit bliver det
)(
)()12()())1(max(
)())1()(()(
2
2
2
22
10
ncn
nnccnnqnccq
nqnTqTMaxnTnq
Θ=
≤
Θ+−−≤
Θ+−−+≤
Θ+−−+=−≤≤
))(()( nnLogOnT =
39
Det var så det, eller …. ???
40
Dagsorden
• Heap sort• Hvad er en heap?• Basale heap operationer• Vedligeholdelse af heap egenskabet under sortering• Gennemgang af heap sort via eksempel• Anvendelse af heap sort: Prioritetskøer
• Quick sort• Virkemåde• Partitionering af array• Ydelse af quick sort• Effektivisering vha. randomiseret input
• Opsummering og konklusion• Opgaver
41
Opsummering og konklusion
• Heap sort
42
Dagsorden
• Heap sort• Hvad er en heap?• Basale heap operationer• Vedligeholdelse af heap egenskabet under sortering• Gennemgang af heap sort via eksempel• Anvendelse af heap sort: Prioritetskøer
• Quick sort• Virkemåde• Partitionering af array• Ydelse af quick sort• Effektivisering vha. randomiseret input
• Opsummering og konklusion• Opgaver
43
Opgaver
• Redegør for hvorfor den største undergren i en heap er 2n/3 (slide 12)
• Lav en implementering af en, eller begge af de nævnte algoritmer og prøv at måle tider på udførsel af algoritmerne• Prøv at lave meget store arrays (f.eks. Ved brug af
tilfældighedsgenerator til generering af data til test)• Formål: at få en praktisk fornemmelse for algoritme kompleksitet
• Øvelse 6.4-1, 6.4-3,
• Øvelse 6.5-3
• Øvelse 7.2-4