Sorteringsproblemet. Gitt en array A med n elementer som kan sammenlignes med hverandre:

Like dokumenter
Hvor raskt klarer vi å sortere?

Logaritmiske sorteringsalgoritmer

Datastrukturer for rask søking

Søkeproblemet. Gitt en datastruktur med n elementer: Finnes et bestemt element (eller en bestemt verdi) x lagret i datastrukturen eller ikke?

Heap* En heap er et komplett binært tre: En heap er også et monotont binært tre:

Binær heap. En heap er et komplett binært tre:

INF2220: Time 12 - Sortering

Rekursiv programmering

Heap og prioritetskø. Marjory the Trash Heap fra Fraggle Rock

TDT4105 Informasjonsteknologi, grunnkurs

Definisjon: Et sortert tre

Hvorfor sortering og søking? Søking og sortering. Binære søketrær. Ordnet innsetting forbereder for mer effektiv søking og sortering INF1010 INF1010

Definisjon av binært søketre

INF1010 notat: Binærsøking og quicksort

Øvingsforelesning 6. Sorteringsalgoritmer. Kristian Veøy

Definisjon. I et binært tre har hver node enten 0, 1 eller 2 barn

Øvingsforelesning 6. Sorteringsalgoritmer. Martin Kirkholt Melhus Basert på foiler av Kristian Veøy 30/09/14 1

Først litt praktisk info. Sorteringsmetoder. Nordisk mesterskap i programmering (NCPC) Agenda

Rekursiv programmering

Hashing: Håndtering av kollisjoner

Dagens tema. Sortering. Fortsettelse om programmering vha tråder.

Kap.8 Sortering og søking sist oppdatert 16.03

Quicksort. Fra idé til algoritme.

Innhold. Innledning 1

Heapsort. Lars Vidar Magnusson Kapittel 6 Heaps Heapsort Prioritetskøer

Quicksort. Lars Vidar Magnusson Kapittel 7 Quicksort Randomisert Quicksort Analyse av Quicksort

Et eksempel: Åtterspillet

Dagens tema. Sortering. Fortsettelse om programmering vha tråder.

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

Pensum: fra boken (H-03)+ forelesninger

Et eksempel: Åtterspillet

Liste som abstrakt konsept/datatype

alternativer til sortering og søking binære trær søketrær Ikke-rekursiv algoritme som løser Hanois tårn med n plater

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

Pensum: fra boken (H-03)+ forelesninger

NITH PG4200 Algoritmer og datastrukturer Løsningsforslag Eksamen 4.juni 2013

deeegimnoorrrsstt Sjette forelesning

INF2220: Time 4 - Heap, Huffmann

Palindrom - iterativt

En implementasjon av binærtre. Dagens tema. Klassestruktur hovedstruktur abstract class BTnode {}

Løsningsforslag for Obligatorisk Oppgave 2. Algoritmer og Datastrukturer ITF20006

Pensum: 3. utg av Cormen et al. Øvingstime: I morgen, 14:15

EKSAMEN. Dato: 28. mai 2018 Eksamenstid: 09:00 13:00

Dagens temaer. Sortering: 4 metoder Søking: binærsøk Rekursjon: Hanois tårn

INF2220 høsten 2017, 19. okt.

Algoritmer - definisjon

O-notasjon og kompleksitet

n/b log b n = (lg n) a log b n = n log b a

Backtracking som løsningsmetode

Algoritmer - definisjon

UNIVERSITETET I OSLO

Binære trær: Noen algoritmer og anvendelser

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

Løsningsforslag til eksamen i fag SIF8010 Algoritmer og Datastrukturer Tirsdag 14. Desember 1999, kl

TDT4110 Informasjonsteknologi grunnkurs: Tema: Algoritmer i praksis. Professor Alf Inge Wang

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

Læringsmål og pensum. Algoritmeeffektivitet

Sortering i Lineær Tid

Rekursjon. Binærsøk. Hanois tårn.

Hva er en kø? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn først

8NH )RUHOHVQLQJ 'HSDUWPHQWÃRIÃ,QIRUPDWLFVÃ8QLYHUVLW\ÃRIÃ2VORÃ1RUZD\,1) ± $OJRULWKPVÃÉÃ'DWDÃ6WUXFWXUHV

ALGORITMER OG DATASTRUKTURER

Python: Rekursjon (og programmering av algoritmer) Python-bok: Kapittel 12 + teoribok om Algoritmer

Oppgave 1 a. INF1020 Algoritmer og datastrukturer. Oppgave 1 b

NITH PG4200 Algoritmer og datastrukturer Løsningsforslag Eksamen 4.juni 2013

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

Løsnings forslag i java In115, Våren 1999

INF1010 Sortering. Marit Nybakken 1. mars 2004

Når Merge sort og Insertion sort samarbeider

Algoritmer og Datastrukturer

Flerveis søketrær og B-trær

Selv-balanserende søketrær

Algoritmer og datastrukturer Kapittel 1 - Delkapittel 1.3

INF Algoritmer og datastrukturer

INF Algoritmer og datastrukturer

UNIVERSITETET I OSLO

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

Backtracking som løsningsmetode

UNIVERSITETET I OSLO

INF2220 høsten 2017, 12. okt.

Algoritmer og Datastrukturer

Øvingsforelesning 3: Splitt og hersk. Daniel Solberg

Algoritmer og Datastrukturer IAI 21899

INF Algoritmer og datastrukturer

Ny/utsatt EKSAMEN. Dato: 5. januar 2018 Eksamenstid: 09:00 13:00

Binære søketrær. Et notat for INF1010 Stein Michael Storleer 16. mai 2013

UNIVERSITETET I OSLO

UNIVERSITETET I OSLO

Vi skal se på grafalgoritmer for:

UNIVERSITETET I OSLO

Løsningsforslag til eksamen i PG4200 Algoritmer og datastrukturer 10. desember 2014

Hva er en stack? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn sist

Hva er en stack? En lineær datastruktur der vi til enhver tid kun har tilgang til elementet som ble lagt inn sist

NORGES INFORMASJONSTEKNOLOGISKE HØGSKOLE PG4200 Algoritmer og datastrukturer

Fig1. Den konvekse innhyllinga av 100 tilfeldige punkter i planet (de samme som nyttes i oppgaven.)

IN Algoritmer og datastrukturer

Løsningsforslag for utvalgte oppgaver fra kapittel 3

EKSAMEN. Dato: 9. mai 2016 Eksamenstid: 09:00 13:00

INF Algoritmer og datastrukturer

Eksamen iin115 og IN110, 15. mai 1997 Side 2 Oppgave 1 Trær 55 % Vi skal i denne oppgaven se på en form for søkestrukturer som er spesielt godt egnet

Transkript:

Sortering

Sorteringsproblemet Gitt en array A med n elementer som kan sammenlignes med hverandre: Finn en ordning (eller permutasjon) av elementene i A slik at de står i stigende (evt. avtagende) rekkefølge Det er viktig å kunne sortere effektivt: Sortering er alltid #1 forbruker av prosessortid Raske algoritmer for søking, innsetting og fjerning i datastrukturer krever oftest at dataene er sortert Analyse og utvikling av effektive sorteringsalgoritmer er et sentralt forskningsområde i (klassisk) informatikk

Hvor raskt klarer vi å sortere? Bare det å sjekke om dataene er sortert er O(n) Rett-frem algoritmer er O(n 2 ) Hvis vi sorterer ved å sammenligne og bytte om to og to elementer, kan det bevises at dette ikke kan gjøres raskere enn O(n log(n)) Smarte sorteringsalgoritmer er O(n log(n)) Hvis vi vet mer om dataene kan vi lage O(n) algoritmer som sorterer med andre mekanismer enn parvise sammenligninger og swapping* *: F.eks. counting sort og radix sort fra kapitlet om køer.

Tre klasser av sorteringsalgoritmer Sekvensielle sorterer fra starten av array: Bruker typisk to løkker inne i hverandre, O(n 2 ) Utplukksortering, innstikksortering, bubble sort (Shell sort?) Logaritmiske: Deler arrayen i to deler, sorterer disse rekursivt, O(n log(n)) Quicksort, flettesortering Basert på bruk av spesielle datastrukturer: Alle dataene legges inn i en rask datastruktur og tas ut igjen i sortert rekkefølge, typisk O(n log(n)) Treesort, heapsort

Sortering av arrayer forenkling Læreboka bruker generiske metoder i Java som kan sortere arrayer som inneholder alt, så lenge dataene er Comparable For å fokusere på algoritmene og effektiviteten, og ikke på Java, forenkler vi sorteringsproblemet og programkoden til: Sortering av arrayer som bare innholder heltall

Utplukksortering (selection sort) Går gjennom arrayen n - 1 ganger I gjennomløp nr i (i = 0, 1, 2,, n - 2) : Arrayen er sortert fra starten og t.o.m. indeks i - 1 Finner det minste av de usorterte elementene på indeksene i, i + 1,, n - 1 ( utplukk / selection ) Setter dette minste elementet inn på indeks i med en ombytting (swapping) Etter n 1 gjennomløp står det største elementet igjen på index n 1, og hele arrayen er sortert

Utplukksortering, eksempel 64 25 12 22 11 11 25 12 22 64 11 12 25 22 64 11 12 22 25 64 11 12 22 25 64

Utplukksortering, animasjon

Effektivitet og implementasjon Utplukksortering programmeres enkelt med to løkker inne i hverandre: Ytre løkke går n - 1 ganger Indre løkke går n - 2, n - 3,..., 2, 1 ganger Totalt: O(n 2 ) Effektiviteten av utplukksortering er ikke avhengig av dataene, algoritmen gjør alltid like mange tester og ombyttinger Se Java-koden

Innstikksortering (insertion sort) Går gjennom arrayen n - 1 ganger I gjennomløp nr i (i = 1, 2, 3,, n - 1) : Arrayen er sortert fra starten og t.o.m. indeks i - 1 Setter element nr i inn på riktig plass blant de i - 1 første elementene ( insertion / innstikk ) Innsettingen gjøres ved å bytte element i med foregående element inntil det står riktig i sorteringen Etter n 1 gjennomløp er alle elementer satt inn på riktig plass og hele arrayen er sortert

Innstikksortering, eksempel 3 7 4 9 5 2 6 1 (0 swap) 3 7 4 9 5 2 6 1 (1 swap) 3 4 7 9 5 2 6 1 (0 swap) 3 4 7 9 5 2 6 1 (2 swap) 3 4 5 7 9 2 6 1 (5 swap) 2 3 4 5 7 9 6 1 (2 swap) 2 3 4 5 6 7 9 1 (7 swap) 1 2 3 4 5 6 7 9

Innstikksortering, animasjon

Effektivitet og implementasjon Programmeres med to løkker inne i hverandre: Ytre løkke går n - 1 ganger Indre løkke går inntil element i står riktig, maksimalt: 1, 2, 3,..., n - 1 ganger Worst-case: O(n 2 ) Effektivitet av innstikksort. avhenger av dataene: Er O(n) for nesten sorterte arrayer Gjennomsnittlig (random data) O(n 2 ) Se Java-koden

Innstikksortering av nesten sorterte data, animasjon

Bubble sort * I gjennomløp nummer i, i = 0, 1, 2,,, n - 2 : Arrayen er sortert fra starten og opp t.o.m. indeks i - 1 Setter minste verdi i usortert del av array på indeks i Finner minste verdi ved å starte i indeks n - 1 og swappe med foregående element hvis dette er større Fortsetter å swappe minste nabolement fremover, til det minste av de usorterte elementene står i indeks i Små verdier vil boble oppover i arrayen, store verdier synker nedover ( sink sort / percolation sort ) Etter n 1 gjennomløp er hele arrayen er sortert *: Litt anderledes enn i læreboka

Bubble sort, eksempel, n = 5 i = 0 i = 1 i = 2 i = 3 64 10 12 22 11 10 64 11 12 22 10 11 64 12 22 10 11 12 64 22 64 10 12 11 22 10 64 11 12 22 10 11 64 12 22 10 11 12 22 64 64 10 11 12 22 10 64 11 12 22 10 11 12 64 22 64 10 11 12 22 10 11 64 12 22 10 64 11 12 22

Bubble sort, animasjon

Effektivitet og implementasjon Bubble sort programmeres med to løkker i hverandre: Ytre løkke går n - 1 ganger Indre løkke går n - 1, n - 2, n - 3,..., 2, 1 ganger Alltid O(n 2 ) Effektivitet av bubble sort avhenger av dataene: Går langsomt hvis det er mye ombytting av verdier Kan enkelt programmes til å avbryte med en gang arrayen er sortert (0 swaps i et gjennomløp) Se Java-koden

Sammenligning av O(n 2 ) metoder Effektivitet avhenger av hvor mye flytting av data som gjøres en swap tar mye lenger tid enn en if-test Utplukksortering Forutsigbar, alltid samme effektivitet Instikksortering Ofte mest effektiv, lite swapping Rask for nesten-sorterte arrayer Bedre enn smarte algoritmer for små n Bubble sort Langsom pga. mye swapping, lite brukt Se testprogram for sorteringsalgoritmer

Shell sort: En raskere algoritme Aka. inkrementell sortering og gap sort (Donald Shell, 1959) Sorterer f.eks. hvert 100. element innbyrdes med instikksortering, deretter hvert 50. element, hvert 25. element, hvert 12. element etc., og tilslutt alle elementer i siste gjennomgang Grovsorteringen går raskt for store gaps Hele sorteringen går mye raskere fordi vi hele tiden bruker innstikksortering på en array som etterhvert vil være nesten sortert

Shell sort: Eksempel Shell sort med gap -sekvens 5, 3 og 1: Gap 5: 81 94 11 96 12 35 17 95 28 58 41 75 15 5-sort : 35 17 11 28 12 41 75 15 96 58 81 94 95 Gap 3: 35 17 11 28 12 41 75 15 96 58 81 94 95 3-sort : 28 12 11 35 15 41 58 17 94 75 81 96 95 Gap 1: 28 12 11 35 15 41 58 17 94 75 81 96 95 Ferdig: 11 12 15 17 28 35 41 58 75 81 94 95 96

En annen måte å se på Shell sort Begynner med å dele opp arrayen i mange små lister, som sorteres hver for seg Etter hvert deler vi opp i færre og færre lister som stadig blir lengre Antall elementer som står feil avtar etterhvert som listene blir lengre, lange lister vil være nesten sortert Instikksortering blir derfor effektivt å bruke fordi det etterhvert er svært lite swapping Se eksempel på neste side med n = 16, der vi bruker gap-sekvensen: 8, 4, 2, 1

23 42 18 96 77 30 11 87 54 29 74 16 56 48 79 33 23 42 18 96 77 30 11 87 23 29 18 16 56 30 11 33 54 29 74 16 56 48 79 33 54 42 74 96 77 48 79 87 23 29 18 16 56 30 11 33 54 42 74 96 77 48 79 87 23 29 18 16 23 29 11 16 56 30 11 33 54 30 18 33 54 42 74 96 56 42 74 87 77 48 79 87 77 48 79 96 23 29 11 16 54 30 18 33 56 42 74 87 77 48 79 96 23 29 11 16 11 16 18 29 54 30 23 30 18 33 54 33 56 42 56 42 74 87 74 48 77 48 77 87 79 96 79 96 11 16 18 29 23 30 54 33 56 42 74 48 77 87 79 96

Implementering av Shell sort Shell sort programmeres med tre løkker, programkoden blir forbausende(?) enkel Ytre løkke går gjennom hele gap-sekvensen, f.eks. n/2, n/4, n/8, n/16,, 1 De to indre løkkene gjør innstikksortering av hver av de mindre listene som fremkommer for hvert gap Se Java-koden

Shell sort: Animasjon

Effektivitet av Shell sort Kan bevises at gjennomsnittlig arbeidsmenge for standard Shell sort er ca. O(n 3/2 ) = O(n n) Er mye raskere enn O(n 2 )-metoder for store n Effektiviteten avhenger av valget av gap -sekvens: Shells opprinnelige forslag: n/2, n/4, n/8,..., 2, 1 Bedre: Rund av hvert gap til nærmeste oddetall Erfaring viser at en enda bedre sekvens er: n/2, (n/2) / (2.2), (n/2) / (2.2 2 ), (n/2) / (2.2 3 ),..., 1 Se testprogram

Andre sekvensielle sorteringer Finnes mange andre forbedringer og varianter av sekvensielle algoritmer i tillegg til Shell sort, f.eks: Comb sort Cocktail shaker sort Odd-even sort Alle disse er polynomiske, og vil derfor være mindre effektive for store verdier av n enn smarte logaritmiske metoder som er O(n log(n))

Logaritmiske sorteringsalgoritmer Rekursive splitt og hersk metoder Deler verdiene i arrayen i to (helst) omtrent like store deler i henhold til et eller annet delingskriterium Hver mindre del sorteres rekursivt på samme måte De to mindre delene settes deretter sammen til en hel ferdig sortert array To logaritmiske metoder i dette kurset: Quicksort Flettesortering

Effektivitet av logaritmiske sorteringsalgoritmer Hvis vi deler arrayen i to omtrent like store deler hver gang, blir det ca. log(n) nivåer med rekursive kall Hvis arbeidet som gjøre på hvert nivå samlet er O(n), vil hele sorteringen bli O(n log(n)) Hvis oppdelingen er svært skjev (en stor og en svært liten del) kan vi få opp til n rekursive nivåer, og algoritmens effektivitet kan synke til O(n 2 )

Quicksort Tony Hoare, 1960 Algoritmen eg. laget for automatisk oversetting Oftest meget rask i praksis Virker for generelle sorteringsproblemer Krever svært lite ekstra hukommelse Gjennomsnittlig effektivitet er O(n log(n)) Worst-case er O(n2 )

Quicksort: Sortere array A av lengde n Hvis n > 1: Velg et element p (partisjoneringselement) i A, f.eks. element nr. 0 eller nr. n/2 * Bytt om på elementene i A (partisjonér arrayen) slik at den deles i to deler: Alle elementer som er mindre eller lik p står til venstre Alle elementer som er større enn p står til høyre Partisjoneringselementet p står mellom de to delene Sortér de to delene rekursivt med quicksort, hele arrayen er da ferdig sortert *: Lærebokens valg

Quicksort: Eksempel Bruker første element til å partisjonere delarrayene Nivå 1: 26 33 35 29 19 12 22 19 22 12 26 29 35 33 Nivå 2: 19 22 12 26 29 35 33 12 19 22 26 29 35 33 Nivå 3: 12 19 22 26 29 35 33 12 19 22 26 29 33 35 Ferdig: 12 19 22 26 29 33 35

Quicksort: Et eksempel til Nivå 1: 65 57 81 92 43 31 26 75 13 10 26 57 10 13 43 31 65 75 92 81 Nivå 2: 26 57 10 13 43 31 65 75 92 81 10 13 26 57 43 31 65 75 92 81 Nivå 3: 10 13 26 57 43 31 65 75 92 81 10 13 26 43 31 57 65 75 81 92 Nivå 4: 10 13 26 43 31 57 65 75 81 92 10 13 26 31 43 57 65 75 81 92 Ferdig: 10 13 26 31 43 57 65 75 81 92

Partisjoneringsalgoritmen 6 8 1 4 9 0 3 5 2 7 6 er partisjoneringselement 6 8 1 4 9 0 3 5 2 7 7 står riktig plassert 6 8 1 4 9 0 3 5 2 7 swap 2 og 8 6 2 1 4 9 0 3 5 8 7 1 står riktig plassert 6 2 1 4 9 0 3 5 8 7 4 står riktig plassert 6 2 1 4 9 0 3 5 8 7 swap 5 og 9 6 2 1 4 5 0 3 9 8 7 0 og 3 står riktig plassert 3 2 1 4 5 0 6 9 8 7 swap 6 og 3, ferdig

Quicksort: Animasjon

Effektivitet og implementasjon Implementeres med to rekursive kall, der parameterene er øvre og nedre indeks for arraysegmentet som skal sorteres Skiller ut partisjoneringen i en egen metode Er O(n log(n)) i gjennomsnitt (random data) Hvis partisjoneringen gir mange skjeve oppdelinger (f.eks. ved nesten sorterte data) vil Quicksort dele opp arrayen ~n ganger, og algoritmen blir O(n 2 ) Se Java-koden

Effektivisering av Quicksort Forbedring av valg av partisjoneringselement, for å redusere muligheten for skjev oppdeling: Sammenlign f.eks. elementene på indeksene 0, n/2 og n -1, og bruk verdien som er i midten Ikke la rekursjonen gå helt ned til lengde lik 1: Bruk en enklere og lettere ikke-rekursiv metode, f.eks. innstikksortering, til å sortere korte segmenter av arrayen

Flettesortering (merge sort) John von Neumann(!), 1945 Velegnet for steinalderens sekvensielle lagringsmedia som magnettape, papirtape og hullkort Utmerket for sortering av lenkede lister (oppgave) Garanterer O(n log(n)) effektivitet Standard implementasjon krever bruk av ekstra arrayer til å kopiere dataene frem og tilbake under sorteringen

Flettesortering av array A av lengde n Hvis n > 1: Sortér nedre og øvre halvdel av A hver for seg, rekursivt med flettesortering Flett de to halvdelene sammen til en sortert array Hele arrayen er da ferdig sortert

Flettesortering: Eksempel 26 33 35 29 19 12 22 26 33 35 29 19 12 22 oppdeling 26 33 35 29 19 12 22 oppdeling 26 33 35 29 19 12 22 bunn i rekursjonen 26 33 29 35 12 19 22 fletting 26 29 33 35 12 19 22 fletting 12 19 22 26 29 33 35 ferdig

Fletting av to sorterte arraysegmenter 1 13 24 26 2 15 27 38 1 13 24 26 2 15 27 38 1 1 13 24 26 2 15 27 38 1 2 1 13 24 26 2 15 27 38 1 2 13 1 13 24 26 2 15 27 38 1 2 13 15 1 13 24 26 2 15 27 38 1 2 13 15 24 1 13 24 26 2 15 27 38 1 2 13 15 24 26 1 13 24 26 2 15 27 38 1 2 13 15 24 26 27 1 13 24 26 2 15 27 38 1 2 13 15 24 26 27 38

Flettesortering: Kalltre for n = 7

Flettesortering: Animasjon

Effektivitet og implementasjon Implementeres med to rekursive kall, parametrene er øvre og nedre indeks for arraysegmentet som skal sorteres Flettingen gjøres ved å kopiere dataene over i en ekstra array og deretter flette de to halvdelene tilbake Programmering av flettingen krever litt indeksfikling Er alltid O(n log(n)), men krever O(n) ekstra hukommelse i tillegg til arrayen som sorteres* Se Java-koden *: Flettesortering kan implementeres med konstant plassforbruk, komplisert algoritme

Quicksort vs. flettesortering Quicksort er vesentlig raskere i de aller fleste tilfeller Flettesortering må alltid flytte data mellom temporær og original array og blir derfor langsommere Flettesortering er alltid O(n log(n)), men... Hvis det er viktig med garantert O(n log(n)) oppførsel, er det bedre å bruke en in-house algoritme som ikke swapper så mye, som f.eks. heapsort Se testprogram for sorteringer