• No results found

Sortering. Föreläsning 12 Innehåll. Sortering i Java. Sortering i Java Exempel. Sortering

N/A
N/A
Protected

Academic year: 2022

Share "Sortering. Föreläsning 12 Innehåll. Sortering i Java. Sortering i Java Exempel. Sortering"

Copied!
10
0
0

Loading.... (view fulltext now)

Full text

(1)

Föreläsning 12

Innehåll

Sortering

O(n2)-algoritmer:

urvalssortering insättningssortering O(nlog n)-algoritmer:

Mergesort Quicksort

Datavetenskap (LTH) Föreläsning 12 HT 2017 1 / 38

Sortering

Varför sortera?

För att göra sökning effektivare.

För att förenkla vissa algoritmer.

Varför olika sorteringsalgoritmer?

Olika sorteringsalgoritmer passar bra i olika sammanhang.

Ingen enskild algoritm är bäst i alla möjliga situtioner.

Datavetenskap (LTH) Föreläsning 12 HT 2017 2 / 38

Sortering i Java

I klassen java.util.Arrays finns metoder för att sortera vektorer t ex:

public static void sort(int[] items) public static void sort(Object[] items)

elementen jämförs med compareTo

public static <T> void sort(T[] items, Comparator<?

super T> comp)

elementen jämförs med comp.compare

Exempel:

int[] a = {1, 4, 1, 9, 5, 2, 6};

Arrays.sort(a);

I interfacet java.util.List finns en metod sort för att sortera listan (fungerar alltså för t.ex. ArrayList och LinkedList).

Sortering i Java

Exempel

En vektor med Book-objekt ska sorteras.

Klassen Book:

public class Book implements Comparable<Book> { private String isbn;

private String title;

private String author;

private int nbrPages;

// konstruktor och övriga metoder public int compareTo(Book o) {

return isbn.compareTo(o.isbn);

} }

(2)

Sortering i Java

Comparable

Book[] a = new Book[4];

a[0] = new Book("isbn4", "titleB", "authorC", 125);

a[1] = new Book("isbn3", "titleA", "authorC", 523);

a[2] = new Book("isbn2", "titleD", "authorA", 199);

a[3] = new Book("isbn1", "titleC", "authorB", 278);

...Arrays.sort(a); // sorteras efter isbn-nummer ...

Klassen Book måste implementera interfacet Comparable.

Inuti metoden sort används compareTo för att jämföra elementen.

Datavetenskap (LTH) Föreläsning 12 HT 2017 5 / 38

Sortering i Java

Comparator

Book[] a = new Book[4];

a[0] = new Book("isbn4", "titleB", "authorC", 125);

a[1] = new Book("isbn3", "titleA", "authorC", 523);

a[2] = new Book("isbn2", "titleD", "authorA", 199);

a[3] = new Book("isbn1", "titleC", "authorB", 278);

...// sortera efter titlar

Arrays.sort(a, new TitleComparator());

...

Klass som implementerar interfacet Comparator:

public class TitleComparator implements Comparator<Book> { public int compare(Book b1, Book b2) {

return b1.getTitle().compareTo(b2.getTitle());

} }

Inuti metoden sort används compare för att jämföra elementen.

Datavetenskap (LTH) Föreläsning 12 HT 2017 6 / 38

Sortering i Java

Lambdauttryck

Sortera efter titlar:

Arrays.sort(a, (b1, b2) ->

b1.getTitle().compareTo(b2.getTitle()) );

Sortera efter antal sidor:

Arrays.sort(a, (b1, b2) -> b1.nbrPages() - b2.nbrPages() );

Istället för att skriva en klass som implementerar interfacet Comparator kan vi använda ett lambdauttryck.

Inuti metoden sort används compare för att jämföra elementen.

Kommentar: om subtraktion i Comparator

I föregående bild används subtraktion för att få ett värde < 0, == 0, > 0:

b1.nbrPages() - b2.nbrPages()

Differensen får fel tecken om termerna är väldigt stora (i storleksordningen Integer.MAX_VALUE eller MIN_VALUE), och har olika tecken. Problemet kallas overflow, och har att göra med att datatypen int har ett begränsat maximalt antal siffror (32 bitar, binära siffror).

Overflow kan inte inträffa i vårt exempel med böcker och sidantal. (Varför?) Om man hanterar stora tal kan hjälpmetoden Integer.compare användas:

Arrays.sort(a, (b1, b2) ->

Integer.compare(b1.nbrPages(), b2.nbrPages()) );

Du kan läsa mer om overflow i lösningsförslaget till övningen om lambda-uttryck (se kurssidan, cs.lth.se/edaa01ht/oevningar).

(3)

Urvalsortering i vektor

Urvalsortering(eng. selection sort)

Sök minsta elementet i den osorterade delen av vektorn och byt plats med första osorterade element (first = första elementet i den osorterade delen):

3.5 6.2 2.8 5.0 1.1 4.5 first

min

1.1 6.2 2.8 5.0 3.5 4.5 first min

1.1 2.8 6.2 5.0 3.5 4.5 first min

1.1 2.8 3.5 5.0 6.2 4.5 first min

1.1 2.8 3.5 4.5 6.2 5.0 first min

1.1 2.8 3.5 4.5 5.0 6.2

Tidskomplexitet: n 1 + n 2 + ... + 1 = O(n2)

Datavetenskap (LTH) Föreläsning 12 HT 2017 9 / 38

Urvalssortering

Tidskomplexitet är O(n2).

Efter k pass är de k minsta (eller största) elementen sorterade. Kan därför vara lämplig om man bara vill få fram de k minsta (eller största) och k är litet.

Tidskomplexitet är då O(k ⇤ n)

Datavetenskap (LTH) Föreläsning 12 HT 2017 10 / 38

Insättningssortering i vektor

Insättningssortering(eng.insertion sort)

Element på plats k i vektorn sätts in på rätt plats bland de redan sorterade elementen på platserna 0..k 1

Detta görs för k = 1, 2, . . . , n

3.5 6.2 2.8 5.0 1.1 4.5 sort osort

3.5 6.2 2.8 5.0 1.1 4.5

2.8 3.5 6.2 5.0 1.1 4.5

2.8 3.5 5.0 6.2 1.1 4.5

1.1 2.8 3.5 5.0 6.2 4.5

1.1 2.8 3.5 4.5 5.0 6.2 sort

osort sort

osort sort

osort sort

osort sort

Tidskomplexitet (värstafall):

1 + 2 + 3 + . . . + n 1 = n(n 1)/2 = O(n2).

Även medelfallet kan visas vara O(n2).

Diskutera

Blir urvalssortering snabbare eller långsammare om vektorns element råkar vara sorterade i stigande ordning?

Blir insättningssortering snabbare eller långsammare om vektorns element råkar vara sorterade i stigande ordning?

(4)

Insättningssortering

public static <T extends Comparable<? super T>> void sort(T[] a) { for (int i = 1; i < a.length; i++) {

T nextVal = a[i];

int nextPos = i;

while (nextPos > 0 &&

nextVal.compareTo(a[nextPos - 1]) < 0) { a[nextPos] = a[nextPos - 1];

nextPos--;

}a[nextPos] = nextVal;

} }

Datavetenskap (LTH) Föreläsning 12 HT 2017 13 / 38

Insättningssortering

Tidskomplexitet är O(n2) i värsta fall och i medelfall.

Dock bra metod om vektorn är ”nästan” sorterad från början:

Om vektorn är sorterad utförs bara en jämförelse per pass – tidskomplexiteten blir då O(n).

Om vektorn består av n sorterade element följda av k osorterade behövs endast k pass.

Man börjar med att sortera in det (n + 1):a sedan det (n + 2):a o s v. I varje pass görs i värsta fall O(n) jämförelser.

Totalt O(k ⇤ n) d.v.s. O(n) om k är litet i förhållande till n.

Datavetenskap (LTH) Föreläsning 12 HT 2017 14 / 38

Mergesort

Sortera med söndra- och härskateknik

Sortera vänstra halvan Sortera högra halvan

Samsortera de båda sorterade halvorna

7 2 5 9 3 8 10 2

2 5 7 9 2 3 8 10

2 2 3 5 7 8 9 10

Merge – samsortering av sorterade följder

Algoritm

Givet två följder v1 och v2 med element sorterade i växande ordning.

Samsortera till en följd res.

Algoritm:

i = j = k = 0

så länge det finns obehandlade element kvar i både v1 och v2 jämför elementet i v1[i] med elementet i v2[j]

om det minsta elementet är från v1 res[k] = v1[i]

i = i + 1 annars

res[k] = v2[j]

j = j + 1 k = k + 1

En av följderna v1 och v2 har obehandlade element kvar.

Flytta dessa element till res.

(5)

Samsortering av sorterade följder – exempel

1 4 6 6 2 4 7 res

v1 v2

1 4 6 6 2 4 7 res

v1 v2

1

2 4 7 res

v1 v2

1 2

2 4 7 res

v1 v2

1 2 4 1 4 6 6 1 4 6 6

1 4 6 6 2 4 7 res

v1 v2 2 4 7

res v1 v2

1 2 4 4 1 4 6 6

1 2 4 4 6

1 4 6 6 2 4 7 res

v1 v2

1 2 4 4 6 6

1 4 6 6 2 4 7 res

v1 v2

1 2 4 4 6 6 7

Datavetenskap (LTH) Föreläsning 12 HT 2017 17 / 38

Samsorteringen i Mergesort

I samsorteringssteget i Mergesort (merge) motsvaras de båda följderna v1 och v2 av de båda sorterade vektorhalvorna.

Det går inte att utföra samsorteringen i den ursprungliga vektorn. En hjälpvektor, lika stor som den som ska sorteras, behövs.

När man i merge-steget skall slå samman två delvektorer:

används motsvarande utrymme i hjälpvektorn (tmpArray):

Resultatet flyttas sedan tillbaka till ursprungsvektorn.

Datavetenskap (LTH) Föreläsning 12 HT 2017 18 / 38

Samsorteringen i Mergesort

Exempel

Slå samman delvektorerna v1 och v2 i vektorn a (bestående av ett element vardera):

Resultatet flyttas sedan tillbaka till den ursprungliga vektorn.

7 2 5 9 3 8 10 2

2 7

tmpArray a

2 7 5 9 3 8 10 2

a

merge – implementeringsskiss

Slå samman de sorterade delvektorerna a[leftPos] .. a[rightPos - 1]

och a[rightPos] .. a[rightEnd]:

private static <T extends Comparable<? super T>> void merge(T[] a, T[] tmpArray, int leftPos, int rightPos, int rightEnd) { int leftEnd = rightPos - 1;

int tmpPos = leftPos;

...

leftPos rightPos rightEnd

(6)

merge – implementeringsskiss

Forts

while (leftPos <= leftEnd && rightPos <= rightEnd) { if (a[leftPos].compareTo(a[rightPos]) <= 0) {

tmpArray[tmpPos] = a[leftPos];

leftPos++;

} else {

tmpArray[tmpPos] = a[rightPos];

rightPos++;

}tmpPos++;

}

/* Nu är en av delvektorerna tom. Kopiera över resten av elementen i den icke tomma vektorn till tmpArray */

/* Flytta till sist tillbaks elementen från tmpArray till motsvarande platser i a */

}

Datavetenskap (LTH) Föreläsning 12 HT 2017 21 / 38

Mergesort – implementering

/** Sorterar elementen i vektora a */

public static <T extends Comparable<? super T>> void

sort(T[] a) { T[] tmpArray = (T[]) new Comparable[a.length];

mergeSort(a, tmpArray, 0, a.length - 1);

}

private static <T extends Comparable<? super T>> void

mergeSort(T[] a, T[] tmpArray, int first, int last) { if (first < last) {

int mid = first + (last - first) / 2;

mergeSort(a, tmpArray, first, mid);

mergeSort(a, tmpArray, mid + 1, last);

merge(a, tmpArray, first, mid + 1, last);

} }

Datavetenskap (LTH) Föreläsning 12 HT 2017 22 / 38

Stabila sorteringsalgoritmer

Stabila sorteringsalgoritmer

Bibehåller ordningen för element med lika nycklar efter sorteringen.

Exempel: Antag att vi har personer ordnade efter förnamn:

Ada Andersson, Bo Eriksson, Lars Andersson, Lena Andersson Om vi vill sortera efter efternamn istället, men samtidigt bibehålla den tidigare ordningen mellan förnamnen så måste vi använda en stabil sorteringsalgoritm.

Ada Andersson, Lars Andersson, Lena Andersson, Bo Eriksson Är mergesort stabil?

Mergesort – tidskomplexitet

Att samsortera två sorterade delvektorer av sammanlagd storlek n kostar ⇡ n.

1 merge av två delvektorer av storlek n/2, kostnad n 2 merge av två delvektorer av storlek n/4, kostnad 2 ⇤ n/2 = n 4 merge av två delvektorer av storlek n/8, kostnad 4 ⇤ n/4 = n

Antal nivåer = log n =) total kostnad ⇡ n log n

(7)

Quicksort

Söndra- och härskaalgoritm.

Oftast snabb

Sämre än Mergesort i värsta fall – O(n2).

Bra (snabb) i medelfall – O(n log n).

Värstafallet kan göras statistiskt osannolikt.

Inget extra minnesutrymme för temporär vektor krävs.

Datavetenskap (LTH) Föreläsning 12 HT 2017 25 / 38

Quicksort – algoritm

Välj ut ett element (pivotelement).

Se till att det hamnar på rätt plats:

Flytta om elementen så att element  pivot hamnar till vänster och element pivot hamnar till höger.

Kallas partitioneringav vektorn.

x

≤ x x

Pivot-elementet, på rätt plats

Upprepa rekursivt på de båda delvektorerna till vänster respektive till höger om pivotelementet.

Datavetenskap (LTH) Föreläsning 12 HT 2017 26 / 38

Quicksort – implementering

public static <T extends Comparable<? super T>> void sort(T[] a) { quickSort(a, 0, a.length - 1);

}

/* Privat hjälpmetod.

Sorterar delvektorn a[first]..a[last]

private static <T extends Comparable<? super T>> void*/

quickSort(T[] a, int first, int last) { if (first < last) {

int pivIndex = partition(a, first, last);

quickSort(a, first, pivIndex - 1);

quickSort(a, pivIndex + 1, last);

} }

Quicksort – val av pivot

I princip kan vilket element som helst väljas.

Vi börjar för enkelhets skull med att välja första elementet i vektorn.

Inte särskilt bra val. Vi återkommer senare med en diskussion om bättre val.

(8)

Quicksort – partitioneringssteget

Sök från vänster upp ett element som är pivot.

Sök från höger upp ett element som är  pivot.

Byt plats på dessa.

Fortsätt tills hela vektorn genomletats.

Pivotelementet kan sättas in mellan de båda vektordelarna som uppstår.

Arbetet blir proportionellt mot vektorns längd.

Datavetenskap (LTH) Föreläsning 12 HT 2017 29 / 38

Partitionering – exempel

6 1 8 9 4 3 5 2 0

pivot = 6 7

6 1 0 9 4 3 5 2 8 7

6 1 0 9 4 3 5 2 8 7

6 1 0 2 4 3 5 9 8 7

Efter byte:

Efter byte:

6 1 0 2 4 3 5 9 8 7

Byt plats på detta och pivot

5 1 0 2 4 3 6 9 8 7

pivot

Datavetenskap (LTH) Föreläsning 12 HT 2017 30 / 38

Partitionering – sorterad vektor

Dåligt val av pivot

Om vektorn är sorterad och om pivot väljs som första elementet hamnar Quicksort i sitt värsta fall:

1 2 3 4 5 6 7 8

pivot = 1

Byt plats på detta och pivot

1 2 3 4 5 6 7 8

pivot Tom vektordel till vänster Alla element utom ett till höger Detta upprepas i alla rekursiva upplagor.

Quicksort – tidskomplexitet

Man kan visa att det bästa fallet för Quicksort är när vektorn delas mitt itu i varje rekursiv upplaga.

Då är tidskomplexiteten = O(n log n)

x

≤ x pivot ≥ x

Sämsta fall är när den ena delvektorn blir tom i varje rekursiv upplaga.

Då är tidskomplexiteten = O(n2)

x

≥ x pivot

(9)

Quicksort – bättre val av pivot

Välj median av första, mittersta och sista elementet.

Eliminerar riskerna i samband med sorterad eller nästan sorterad indata.

6 1 4 9 8 3 5 2 7 0

left mid right

Sortera de tre elementen i växande ordning:

0 1 4 9 6 3 5 2 7 8

left mid right

pivot Median av de tre är nu mittelementet.

Datavetenskap (LTH) Föreläsning 12 HT 2017 33 / 38

Quicksort – bättre val av pivot

Forts

Byt elementet på plats mid med elementet på plats left.

Då hamnar pivotelementet längs till vänster precis som förut.

6 1 4 9 0 3 5 2 7 8

pivot

Nu kan partitioneringssteget utföras som förut.

Datavetenskap (LTH) Föreläsning 12 HT 2017 34 / 38

Varianter av partitioneringssteget

Stanna eller ej (och byta) vid likhet med pivot?

Om vi inte stannar och byter och alla nycklar är lika hamnar vi i sämsta fallet.

5 5 5 5 5 5 5 5 5 5

pivot

Om vi stannar och byter och alla nycklar är lika blir det bästa fallet.

5 5 5 5 5

5 5 5 5 5

5 5 5 5 5

5 5 5 5 5

pivot

Man brukar rekommendera att stanna och byta vid likhet.

Quicksort – efter partitioneringen

Efter partitioneringen sorteras delvektorerna

a[low]. . . a[pivIndex-1] och a[pivIndex+1]. . . a[high] rekursivt.

I praktiken låter man av effektivitetsskäl metoden avstanna när delvektorn i det rekursiva anropet är mindre än 10-20.

Den då nästan färdigsorterade vektorn kan sorteras av någon metod som är bra på nästan sorterad indata. T.ex. är insättningssortering lämplig.

(10)

Sortering

Exempel på vad du ska kunna

Redogöra för och jämföra olika sorteringsalgoritmer:

Insättningssortering i vektor Urvalssortering i vektor

Heapsort (behandlas i samband med prioritetsköer).

Mergesort Quicksort

Genomföra sortering på enkla exempel med ovan nämnda metoder Samsortera två sorterade följder

Förklara begreppen pivot-element och partitionering (Quicksort).

Använda idéerna från sorteringsalgoritmerna för att lösa andra problem (t.ex. partionering från quicksort eller sammanslagning av sorterade följder från mergesort).

Datavetenskap (LTH) Föreläsning 12 HT 2017 37 / 38

Datorlaboration 6

Map, hashtabell

Implementera en map med en egen öppen hashtabell.

valuekey null

null null null ...

0 1 2 3 4 ...

table.length -1

next null valuekey

next

valuekey null next

Tips:

Det ska vara en öppen hashtabell.

Entry-objekten fungerar även som noder i en enkellänkad lista.

Innehåll: abstrakta datatypen map, öppen hashtabell, länkade listor, generisk klass

Datavetenskap (LTH) Föreläsning 12 HT 2017 38 / 38

References

Related documents

För att spara minne har du valt att lagra detta som en array där varje element innehåller beteckningen på ett prov som tagits.. För att underlätta för läkarna vill du

HiveMQ har tagit fram en anpassad server (broker), för att användas över MQTT och tillämpa MQTT standarden fullt ut. Den lämpar sig för M2M kommunikation och

Detta dokument har till syfte att beskriva vilka lås inom Disklocksystemet som ska samlas in under den övergångsperiod som projektet fortskrider samt hur dessa lås identifieras

För alla rader som börjar på med ett nummer-tecken(#) så skapas ett nytt grupp-objekt med samma namn som radens innehåll. Grupperna som skapas adderas till samlingen av

Sök i varje iteration i den osorterade sekvensen efter det minsta kvarvarande datat och lägg det till slutet av den sorterade sekvensen. rakt

The most complicated combinations can readily be counted with comparatively few counters or relays by first assorting the cards according to the first items entering into

Detta är inte fallet för en Digital Model (DM) som kommer att användas i denna studie, det är alltså digital representation av ett befintligt eller planerat fysiskt ob- jekt,

Tips Eleverna kan tävla gruppvis om att komma på flest passande egenskapsord.. Eleverna kan välja två egenskaper, göra en tabell av typen