Mm6: More sorting algorithms: Heap sort and quick sort...

Post on 22-May-2020

13 views 0 download

Transcript of Mm6: More sorting algorithms: Heap sort and quick sort...

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