Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6

Relevanta dokument
Föreläsning 5 Innehåll

Föreläsning 5 Innehåll. Val av algoritm och datastruktur. Analys av algoritmer. Tidsåtgång och problemets storlek

Asymptotisk komplexitetsanalys

Algoritmer och effektivitet. Föreläsning 5 Innehåll. Analys av algoritmer. Analys av algoritmer Tidskomplexitet. Algoritmer och effektivitet

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Föreläsning 2 Datastrukturer (DAT037)

Lösningsförslag till tentamen Datastrukturer, DAT037,

Tommy Färnqvist, IDA, Linköpings universitet. 1 ADT Map/Dictionary Definitioner Implementation... 2

Föreläsning 2 Datastrukturer (DAT037)

Lösningsförslag för tentamen i Datastrukturer (DAT037) från

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 5 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen med lösningsförslag Datastrukturer för D2 DAT 035

Sökning och sortering

Föreläsning Datastrukturer (DAT036)

Grundläggande datalogi - Övning 4

Föreläsning 1. Introduktion och sökning i graf. Vad är en algoritm?

Datastrukturer. föreläsning 3. Stacks 1

Datastrukturer, algoritmer och programkonstruktion (DVA104, HT 2014) Föreläsning 5

Datastrukturer och algoritmer

Länkade strukturer, parametriserade typer och undantag

Lösningar Datastrukturer TDA

Tentamen'('Datastrukturer,'algoritmer'och'programkonstruktion.'

Föreläsning 5: Kardinalitet. Funktioners tillväxt

Tentamen i Algoritmer & Datastrukturer i Java

Programmering för språkteknologer II, HT2014. Rum

Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016

Programkonstruktion och Datastrukturer

Innehåll. Föreläsning 12. Binärt sökträd. Binära sökträd. Flervägs sökträd. Balanserade binära sökträd. Sökträd Sökning. Sökning och Sökträd

Tommy Färnqvist, IDA, Linköpings universitet

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen Datastrukturer, DAT037 (DAT036)

Algoritmer och datastrukturer 2012, fo rela sning 8

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Vad har vi pratat om i kursen?

Föreläsning Datastrukturer (DAT036)

Tentamen i Algoritmer & Datastrukturer i Java

Fredag 10 juni 2016 kl 8 12

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Magnus Nielsen, IDA, Linköpings universitet

Några svar till TDDC70/91 Datastrukturer och algoritmer

Föreläsning 6: Introduktion av listor

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016

Lösningsförslag för tentamen i Datastrukturer (DAT036) från

Föreläsning Datastrukturer (DAT037)

Trädstrukturer och grafer

Föreläsning Datastrukturer (DAT036)

Föreläsning 9 Datastrukturer (DAT037)

Algoritmer och datastrukturer TDA143

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Övning 2. (Länkade) Listor, noder

Översikt. Stegvis förfining. Stegvis förfining. Dekomposition. Algoritmer. Metod för att skapa ett program från ett analyserat problem

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

Föreläsning 13 Datastrukturer (DAT037)

Bakgrund och motivation. Definition av algoritmer Beskrivningssätt Algoritmanalys. Algoritmer. Lars Larsson VT Lars Larsson Algoritmer 1

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 5 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Algoritmer, datastrukturer och komplexitet

Föreläsning 2. Länkad lista och iterator

Sökning. Översikt. Binärt sökträd. Linjär sökning. Binär sökning. Sorterad array. Linjär sökning. Binär sökning Hashtabeller

Tommy Färnqvist, IDA, Linköpings universitet

Föreläsning 4 Datastrukturer (DAT037)

Dugga Datastrukturer (DAT036)

Algoritmer, datastrukturer och komplexitet

Föreläsning 10 Datastrukturer (DAT037)

Tentamen Datastrukturer (DAT036)

Lösningsförslag till tentamen Datastrukturer, DAT037 (DAT036), Tiden det tar att utföra en iteration av loopen är oberoende av värdet på

Föreläsning 4 Innehåll

Algoritmer, datastrukturer och komplexitet

Lösningsförslag till exempeltenta 1

Föreläsning 4. ADT Kö Kö JCF Kö implementerad med en cirkulär array Kö implementerad med en länkad lista

Föreläsning 6 Datastrukturer (DAT037)

Programmering för språkteknologer II, HT2014. Rum

Föreläsning 1 Datastrukturer (DAT037)

Tentamen i Algoritmer & Datastrukturer i Java

Magnus Nielsen, IDA, Linköpings universitet

Föreläsning 1. Introduktion. Vad är en algoritm?

Tentamen Datastrukturer D DAT 035/INN960

Föreläsning 5. Rekursion

Föreläsning 8 Datastrukturer (DAT037)

Tommy Färnqvist, IDA, Linköpings universitet. 2 Rekursion i C Implementation av rekursion Svansrekursion En till övning...

Datastrukturer och algoritmer. Föreläsning 15 Inför tentamen

Exempeltenta GruDat 2002/2003

Tentamen i Algoritmer & Datastrukturer i Java

Tentamen kl Uppgift 4. Uppgift 5

Teoretisk del. Facit Tentamen TDDC (6)

Självbalanserande träd AVL-träd. Koffman & Wolfgang kapitel 9, avsnitt 1 2

n (log n) Division Analysera skolboksalgoritmen för division (trappdivision). Använd bitkostnad.

Föreläsning Datastrukturer (DAT036)

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning 2. Länkad lista och iterator

Föreläsning 13 Datastrukturer (DAT037)

Föreläsning 7. Träd och binära sökträd

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition

Föreläsning Datastrukturer (DAT036)

Tabeller. Programkonstruktion. Moment 8 Om abstrakta datatyper och binära sökträd. Implementering av tabellen. Operationer på tabellen

Föreläsning 9 Innehåll

Dekomposition och dynamisk programmering

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom:

Transkript:

Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6?

DAGENS AGENDA Komplexitet Ordobegreppet Komplexitetsklasser Loopar Datastrukturer Några nyttiga regler OBS! Idag jobbar vi med pseudokod

KOMPLEXITET Anta att ADT:n Fält behöver en operation som returnerar vilket index som en viss iterator pekar på (kanske ett meningslöst exempel, men enkelt...). Om x inte pekar på något element i fältet så returneras storleken... En möjlig algoritm: Integer GetIndex(Iterator x) Integer i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next() Return i

KOMPLEXITET Anta att operationen - finns för iteratorer och att den beräknar avståndet mellan två iteratorer (uttryckt i antal element). Följande algoritm är då möjlig Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i

KOMPLEXITET Vi räknar operationerna som kommer att utföras för ett visst indatafall. Operationer är aritmetiska (+, - etc), jämförelser och tilldelningar. Först fallet att det efterfrågade elementet ligger först: Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next()

KOMPLEXITET Vi räknar operationerna som kommer att utföras för ett visst indatafall. Operationer är aritmetiska (+, - etc), jämförelser och tilldelningar. Först fallet att det efterfrågade elementet ligger först: Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next()

KOMPLEXITET För detta fall är algoritmen med iteration effektivast Först fallet att det efterfrågade elementet ligger först: Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i 5 i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next() 3

KOMPLEXITET Vi räknar nu operationer för fallet att det efterfrågade elementet ligger först på plats 1 000 000 Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next()

KOMPLEXITET Vi får nu det omvända förhållandet: algoritmen med loop blir ineffektivare 4 000 000 mot 5 Det efterfrågade fallet ligger på plats 1 000 000 Integer GetIndex(Fält f, Iterator x) Integer i i = x - First() If i < 0 OR i >= Size() then i = NrOfElements() End If Return i 5 i = 0 p = First() While p!= x do If p.isend() then Break End If i = i + 1 p = Next() ca 4 000 000

KOMPLEXITET I detta fall vet vi inte det det exakta antalet iterationer för varje sökning. Vi vet inte heller hur lång tid respektive operation tar, men det är uppenbart att loop-lösningen tar enormt mycket mer datorkraft.

KOMPLEXITET I detta fall vet vi inte det det exakta antalet iterationer för varje sökning. Vi vet inte heller hur lång tid respektive operation tar, men det är uppenbart att loop-lösningen tar enormt mycket mer datorkraft. Om t.ex. Två algoritmer som löser samma problem ska jämföras eller vi vill ha en grov uppfattning om en algoritms komplexitet/effektivitet och mängden data kan vara stor Använd stora ordo, O(x) för att ge en grov bild av komplexiteten

ORDOBEGREPPET Komplexiteten för en algoritm är det antal distinkta steg den kan behöva för att slutföra en beräkning Komplexiteten uttrycks som en funktion av datamängden n n är mängden data som algoritmen behandlar O-notation beskriver prestanda och komplexitet Kan beskriva exekveringstid eller minne

ORDOBEGREPPET Komplexiteten för en algoritm är det antal distinkta steg den kan behöva för att slutföra en beräkning Komplexiteten uttrycks som en funktion av datamängden n n är mängden data som algoritmen behandlar O-notation beskriver prestanda och komplexitet Kan beskriva exekveringstid eller minne Idag kan vi tänka på exekveringstid när vi pratar om komplexitet

ORDOBEGREPPET Komplexiteten för en algoritm är det antal distinkta steg den kan behöva för att slutföra en beräkning Komplexiteten uttrycks som en funktion av datamängden n n är mängden data som algoritmen behandlar O-notation beskriver prestanda och komplexitet Kan beskriva exekveringstid eller minne Idag kan vi tänka på exekveringstid när vi pratar om komplexitet O-notation beskriver (oftast) värsta möjliga scenario

Dessa är de komplexiteter vi kommer att hålla oss till NÅGRA VANLIGA KOMPLEXITETSKLASSER

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma - halverad sökmängd

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma - halverad sökmängd - direkt beroende av n

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma - halverad sökmängd - direkt beroende av n - blandning av log n och n

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma - halverad sökmängd - direkt beroende av n - blandning av log n och n - nästlade loopar i två steg

NÅGRA VANLIGA KOMPLEXITETSKLASSER Dessa är de komplexiteter vi kommer att hålla oss till - alltid samma - halverad sökmängd - direkt beroende av n - blandning av log n och n - nästlade loopar i två steg - nästlade loopar i tre steg

ORDOBEGREPPET Om körtiden för en algoritm inte alls påverkas av antalet element säger man att den är konstant eller O(1) Om körtiden för en algoritm påverkas linjärt av antalet element säger man att den är linjär eller, där n är antalet element Om körtiden för en algoritm påverkas kvadratiskt av antalet element säger man att den är kvadratisk eller O(n²), där n är antalet element Att nollställa en matris är O(m*n) där m är antalet rader och n är antalet kolumner

O(1) Algoritmen kommer alltid att exekvera på samma tid oavsett hur stort indatat är Exempel: bool IsFirstElementNull(String[] strings) If string[0] = NULL then Return true End If Return false

O(LOG N) Algoritmen kommer att exekvera på en tid proportionell till logaritmen av indatats storlek. Detta betyder generellt att algoritmen jobbar med en datamängd som iterativt delas Exempel: Sökning i sorterat binärt träd Binärsökning log(n) < n, när n går mot stora värden Algoritmer som körs i O(log n) använder inte hela indatat

O(N) Algoritmens exekveringstid kommer att växa linjärt och i direkt proportion till indatats storlek Exempel: bool ContainsValue(String[] strings, String value) For i = 0; i < strings.length; i++ do If strings[i] = value then Return true End If Return false

ORDOBEGREPPET 2 algoritmer, A och B, som löser samma typ av problem - Komplexitet på A är 5000n - Komplexitet på B är 1,1 n Indata A B n 5 000n [1,1 n ] 10 50 000 3 100 500 000 13 781 1 000 5 000 000 2,5 * 10 41 1 000 000 5 * 10 9 4,8 * 1041 392

ORDOBEGREPPET 2 algoritmer, A och B, som löser samma typ av problem - Komplexitet på A är 5000n - Komplexitet på B är 1,1 n För n = 10: - A kräver 50 000 steg - B kräver 3 steg B är bättre Indata A B n 5 000n [1,1 n ] 10 50 000 3 100 500 000 13 781 1 000 5 000 000 2,5 * 10 41 1 000 000 5 * 10 9 4,8 * 1041 392

ORDOBEGREPPET B kan inte användas för stora datamängder 2 algoritmer, A och B, som löser samma typ av problem - Komplexitet på A är 5000n - Komplexitet på B är 1,1 n För n = 10: - A kräver 50 000 steg - B kräver 3 steg För n = 1 000: - A kräver 5 000 000 steg - B kräver 2,5 * 10 41 steg B är bättre A är bättre Indata A B n 5 000n [1,1 n ] 10 50 000 3 100 500 000 13 781 1 000 5 000 000 2,5 * 10 41 1 000 000 5 * 10 9 4,8 * 1041 392

ORDOBEGREPPET B kan inte användas för stora datamängder 2 algoritmer, A och B, som löser samma typ av problem - Komplexitet på A är 5000n - Komplexitet på B är 1,1 n För n = 10: - A kräver 50 000 steg - B kräver 3 steg För n = 1 000: - A kräver 5 000 000 steg - B kräver 2,5 * 10 41 steg B är bättre A är bättre Indata A B n 5 000n [1,1 n ] 10 50 000 3 100 500 000 13 781 1 000 5 000 000 2,5 * 10 41 1 000 000 5 * 10 9 4,8 * 1041 392 Vad som är viktigt är hur funktionen växer vid stora n

KÖRTID FÖR OLIKA KOMPLEXITETSKLASSER Algoritmen körs på f(n) mikrosekunder f(n) n = 2 n = 16 n = 256 n = 1024 n = 1 048 576 1 1 1 1 1 1 log2n 1 4 8 10 20 n 2 1,6 * 10 1 2,6 * 10 2 1,02 * 10 3 1,05 * 10 6 n log2n 2 6,4 * 10 1 2,1 * 10 3 1,02* 10 4 2,10 * 10 7 n 2 4 2,6 * 10 2 6,6 * 10 4 1,05 * 10 6 1,10 * 10 12 n 3 8 4,1 * 10 3 1,7 * 10 7 1,07 * 10 9 1,15 * 10 18 2 n 4 6,6 * 10 4 1,2 * 10 77 1,80 * 10 308 6,74 * 10315 652

KÖRTID FÖR OLIKA KOMPLEXITETSKLASSER f(n) n = 2 n = 16 n = 256 n = 1024 n = 1 048 576 1 1 µsec 1 µsec 1 µsec 1 µsec 1 µsec log2n 1 µsec 4 µsec 8 µsec 10 µsec 20 µsec n 2 µsec 16 µsec 260 µsec 1,02 ms 1,05 sec n log2n 2 µsec 64 µsec 2,1 ms 10,2 ms 21 sec n 2 4 µsec 260 µsec 66 ms 1,05 sec 1,8 wks n 3 8 µsec 4,1 ms 17 sec 17,9 min 36 559 yrs 2 n 4 µsec 66 ms 3,7 * 10 63 yrs 5,7 * 10 294 yrs 2,1 * 10 315 639 yrs

KOMPLEXITET Formellt gäller: Om f(n) är en funktion som uttrycker komplexiteten exakt, så är g(n) en övre begränsning, dvs vi kan säga O(g(n)), om det går att välja en konstant K och fixt n 0, så att K * g(n) >= f(n) för alla n > n 0 Dvs om man bortser från små värden och konstanta faktorer så är g(n) större eller lika

KOMPLEXITET Vi kan säga O(g(n)) om det går att välja en konstant K och ett fixt n 0, så att K * g(n) >= f(n) för alla n > n 0

KOMPLEXITET Det är de STORA värdena på n som är intressanta Värsta möjliga scenario! Därför räknar vi inte exakt utan gör en uppskattning baserat på komplexitetklasserna Vi kan säga O(g(n)) om det går att välja en konstant K och ett fixt n 0, så att K * g(n) >= f(n) för alla n > n 0

EXEMPEL En operation Clear() på ADT:n Matrix med m rader och n kolumner. Den nollställer alla matrisens element med hjälp av operationen ClearElement() Clear() Integer i = 0; j = 0 While i < m do While j < n do ClearElement(i, j) j = j + 1 j = 0 i = i + 1

EXEMPEL En operation Clear() på ADT:n Matrix med m rader och n kolumner. Den nollställer alla matrisens element med hjälp av operationen ClearElement() Clear() Integer i = 0; j = 0 While i < m do While j < n do ClearElement(i, j) j = j + 1 j = 0 i = i + 1 Vilken är komplexiteten? Och hur räknar vi ut den? Använd komplexitetsklasserna

EXEMPEL En operation Clear() på ADT:n Matrix med m rader och n kolumner. Den nollställer alla matrisens element med hjälp av operationen ClearElement() Clear() Integer i = 0; j = 0 While i < m do While j < n do ClearElement(i, j) j = j + 1 j = 0 i = i + 1 Vilken är komplexiteten? Och hur räknar vi ut den? Använd komplexitetsklasserna Komplexiteten: O(m*n), ty för varje varv i den yttre loopen (det är m st) kommer hela den inre loopen att snurra n st varv, dvs totalt n*m iterationer av den inre loopens kropp (dvs anrop till ClearElement()):

EXEMPEL Skulle vi räkna mer exakt skulle det bli 4n 2 + 4m + 3 enligt tidigare sätt att räkna operationer. Men vi säger alltså ändå att den är O(n 2 ) Allmänt: endast den terms om har högst dignitet tas med och konstanta faktorer på denna ignoreras. Motivering: För stora mängder av data är det den tyngst vägande termen som kommer att dominera Man kan t.ex. jämföra kurvorna för n 2 + 20n + 400 och n 2. Ju större värden på n, desto mindre relativ skillnad. För 1 miljon är den 0.002%, men för 1 är den 42100%. Det intressanta är beteendet vid stora mängder data.

EXEMPEL Skulle vi räkna mer exakt skulle det bli 4n 2 + 4m + 3 enligt tidigare sätt att räkna operationer. Men vi säger alltså ändå att den är O(n 2 ) Allmänt: endast den terms om har högst dignitet tas med och konstanta faktorer på denna ignoreras. Motivering: För stora mängder av data är det den tyngst vägande termen som kommer att dominera För att inte behöva räkna så mycket använder vi alltså de övergripande komplexitetsklasserna för att beskriva komplexiteten. Man kan t.ex. jämföra kurvorna för n 2 + 20n + 400 och n 2. Ju större värden på n, desto mindre relativ skillnad. För 1 miljon är den 0.002%, men för 1 är den 42100%. Det intressanta är beteendet vid stora mängder data.

ÖVNINGAR A Init(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 a[i].i = i i = i + 1 Vilken Init har högst komplexitet? - kod A eller kod B? B Init(A a[], Integer n) InitD(a, n) InitI(a, n) InitD(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 i = i + 1 InitI(A A[], Integer n) Integer i = 0 While i < n do a[i].i = i i = i + 1 end loop

Loopen körs i värsta fallet n ggr Init(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 a[i].i = i i = i + 1 Båda har komplexiteten Alltså samma! Init(A a[], Integer n) InitD(a, n) InitI(a, n) InitD(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 i = i + 1 InitI(A A[], Integer n) Integer i = 0 While i < n do a[i].i = i i = i + 1 end loop

Loopen körs i värsta fallet n ggr Init(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 a[i].i = i i = i + 1 Båda har komplexiteten Alltså samma! Looperna InitD och InitI körs vardera i värsta fallet n ggr alltså n+n = 2n Init(A a[], Integer n) InitD(a, n) InitI(a, n) InitD(A a[], Integer n) Integer i = 0 While i < n do a[i].d = 42 i = i + 1 InitI(A A[], Integer n) Integer i = 0 While i < n do a[i].i = i i = i + 1 end loop

ÖVNINGAR G(B b[], Integer n) Integer i = 0 While i < n do b[i].c = 0 i = i + 1 Vilken komplexitet har F?? F(A a[], Integer n) Integer i = 0 While i < n do G(a[i].b, n) i = i + 1

I F() körs loopen i värsta fallet n ggr, för varje varv så körs loopen i G() n ggr = n*n O(n 2) G(B b[], Integer n) Integer i = 0 While i < n do b[i].c = 0 i = i + 1 O(n 2 ) F(A a[], Integer n) Integer i = 0 While i < n do G(a[i].b, n) i = i + 1

ÖVNINGAR F(A a[], Integer n) Integer i = 0 While i < n do a[i].x = 0 i = i + 1 Integer j = 0 While j < 2*n do a[j].c = 0 j = j + 1 Vilken komplexitet har F??

Den första loopen körs i värsta fallet n ggr, den andra loopen körs i värsta fallet 2n ggr = n + 2n = 3n F(A a[], Integer n) Integer i = 0 While i < n do a[i].x = 0 i = i + 1 Integer j = 0 While j < 2*n do a[j].c = 0 j = j + 1

ÖVNINGAR 1: 2: F(A a[][], Integer n) While i < n do While j < n do a[i][j] = 7 F(A a[][], Integer n) While i < n do While j < 42 do a[i][j] = 7 Vilken komplexitet har F i de båda fallen??

Den yttre loopen körs i värsta fallet n ggr, den inre loopen körs i värsta fallet n ggr = n*n = n 2 O(n 2) F(A a[][], Integer n) While i < n do While j < n do a[i][j] = 7 O(n 2 ) F(A a[][], Integer n) While i < n do While j < 42 do a[i][j] = 7

Den yttre loopen körs i värsta fallet n ggr, den inre loopen körs i värsta fallet n ggr = n*n = n 2 O(n 2) F(A a[][], Integer n) While i < n do While j < n do a[i][j] = 7 O(n 2 ) Den yttre loopen körs i värsta fallet n ggr, den inre loopen körs i värsta fallet 42 ggr = n*42 = 42n O(n ) F(A a[][], Integer n) While i < n do While j < 42 do a[i][j] = 7

NÄSTLADE LOOPAR Oberoende nästlade loopar: Antalet iterationer i den inre loopen är inte beroende av antalet iterationer i den yttre loopen Exempel: x = 0 For j = 1; j <= n/2; j++ do For k = 1; k <= n*n; k++ do x = x + j + k Den yttre loopen exekverar n/2 gånger. För varje varv i den yttre loopen, exekverar den inre loopen n 2 gånger. Så kroppen till den inre loopen exekverar (n/2)*n 2 = n 3 /2 gånger Algoritmens komplexitet är O(n 3 )

NÄSTLADE LOOPAR Beroende nästlade loopar: Antalet iterationer i den inre loopen beror på ett värde från den yttre loopen Exempel: x = 0 For j = 1; j <= n/2; j++ do For k = 1; k <= 3*j; k++ do x = x + j När j är 1, körs den inre loopen 3 gånger; När j är 2, körs den inre loopen 3*2 gånger;... När j är n, körs den inre loopen 3*n gånger. Totalt körs den inre loopen 3+6+9+...3n = 3(1+2+3+...n) = 3n 2 /2 + 3n/2 gånger. Algoritmens komplexitet är alltså O(n 2 )

NÅGRA ENKLA REGLER OM LOOPAR Det är bara loopar vars antal iterationer som är beroende av indatats storlek som man behöver ta hänsyn till Nästlingen avgör vilket O (ordo) det blir Man måste titta i alla funktioner som anropas O för nästlade loopar multipliceras om de är oberoende O för sekventiella loopar adderas Om två loopar är nästlade på samma nivå i loophierarkin så är det den av looparna som har högst O som man räknar med Bara den största (mest dominanta) termen behålls, resten skippas

KOMPLEXITET FÖR OPERATIONER PÅ DATASTRUKTURER Man kan ofta hitta komplexitet för en operation (på en datastruktur) genom att gå igenom hur den fungerar (och vad den faktiskt gör)

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first O(1) Remove last Remove Find O(1)

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Insert Remove first Remove last O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Insert Remove first Remove last O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Värsta fallet: i början - flytta alla efterföljande för att skapa plats (förutsatt att det finns plats) Remove last O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first Remove last O(1) O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Värsta fallet: i början - flytta alla efterföljande för att skapa plats (förutsatt att det finns plats) Det blir en lucka. Alla kvarvarande element måste flyttas ett steg bakåt Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first Remove last O(1) O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Värsta fallet: i början - flytta alla efterföljande för att skapa plats (förutsatt att det finns plats) Det blir en lucka. Alla kvarvarande element måste flyttas ett steg bakåt Ta bort det med högst index Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first Remove last Remove Find O(1) O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Värsta fallet: i början - flytta alla efterföljande för att skapa plats (förutsatt att det finns plats) Det blir en lucka. Alla kvarvarande element måste flyttas ett steg bakåt Ta bort det med högst index Värsta fallet: i början - flytta alla efterföljande för att täppa till lucka

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Insert first Insert last Insert Remove first Remove last Remove Find O(1) O(1) Alla som redan ligger i arrayen måste flyttas ett steg framåt för att skapa plats (förutsatt att det finns plats) Lägg in på nästa lediga plats (förutsatt att det finns en) Värsta fallet: i början - flytta alla efterföljande för att skapa plats (förutsatt att det finns plats) Det blir en lucka. Alla kvarvarande element måste flyttas ett steg bakåt Ta bort det med högst index Värsta fallet: i början - flytta alla efterföljande för att täppa till lucka Värsta fallet: Det eftersökta finns inte i listan - alla element måste genomsökas

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Insert last O(1) O(1) Insert Remove first O(1) Remove last O(1) O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Insert Remove first O(1) Remove last O(1) O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Remove first O(1) Remove last O(1) O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Värsta fall: I slutet - sök upp noden Remove first O(1) Remove last O(1) O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Remove first O(1) Värsta fall: I slutet - sök upp noden Ta bort vid head Remove last O(1) O(1) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Remove first O(1) Remove last O(1) O(1) Värsta fall: I slutet - sök upp noden Ta bort vid head Ta bort vid tail (föregående nod nås via länk bakåt) Remove Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Remove first O(1) Remove last O(1) O(1) Remove Värsta fall: I slutet - sök upp noden Ta bort vid head Ta bort vid tail (föregående nod nås via länk bakåt) Värsta fall: i slutet - sök upp noden Find

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Insert first O(1) Länka in vid head Insert last O(1) O(1) Länka in vid tail Insert Remove first O(1) Remove last O(1) O(1) Remove Find Värsta fall: I slutet - sök upp noden Ta bort vid head Ta bort vid tail (föregående nod nås via länk bakåt) Värsta fall: i slutet - sök upp noden Värsta fall: finns inte - sök igenom hela listan

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Balanserat Binärt Sökträd Insert first O(1) X Insert last O(1) O(1) X Insert O(log n) Remove first O(1) X Remove last O(1) O(1) X Vid sökning efter rätt plats i trädet halveras sökmängden för varje iteration Remove O(log n) Find O(log n)

KOMPLEXITETER PÅ DATASTRUKTURERNA Värsta fallet: degenererat träd (beter sig som en länkad lista). Sökmängden halveras aldrig utan alla element måste i värsta fallet sökas igenom Lista Array Lista Dubbellänkad lista med head och tail Balanserat Binärt Sökträd Obalanserat Binärt Sökträd Insert first O(1) X X Insert last O(1) O(1) X X Insert O(logn) Remove first O(1) X X Remove last O(1) O(1) X X Remove O(logn) Find O(logn)

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Balanserat Binärt Sökträd Obalanserat Binärt Sökträd Insert first O(1) X X Insert last O(1) O(1) X X Insert O(logn) Remove first O(1) X X Remove last O(1) O(1) X X Remove O(logn) Find O(logn)

KOMPLEXITETER PÅ DATASTRUKTURERNA Lista Array Lista Dubbellänkad lista med head och tail Balanserat Binärt Sökträd Obalanserat Binärt Sökträd Insert first O(1) X X Insert last O(1) O(1) X X Insert O(logn) Remove first O(1) X X Remove last O(1) O(1) X X Remove O(logn) Find O(logn)?