Uploaded by coolbrud.lfk

Begrepp Tenta DoA Uppdaterad vt22

advertisement
Grundbegrepp
•
Algoritm
Ett ändligt set instruktioner för att lösa en specifik väldefinierad uppgift
•
Datatyp
Värdemängd med operationer. (Objekt + operationer)
•
Datastruktur
En datastruktur är en abstrakt beskrivning till skillnad från ‘datatyper’. En datatyp kan vara
exempelvis Integer, String eller boolean. Det har en fast betydelse medan en datastruktur
beskriver något odefinierbart, till exempel en lista eller array.
•
Diskret linjärt ordnad
Ändligt antal ordnade element, med före och efter-relation.
•
Hanterbara problem
Kan lösas praktiskt, t.ex. O(n), O(log n) – komplexiteten är begränsad av ett polynom..
Ohanterliga problem har tidskomplexitet 2^n, n!, n^n, komplexiteten är superpolynom.
•
Traversering
Att besöka varje element exakt en gång, naturlig för datatypen.
•
(Mental) modell för en datatyp
Vardaglig modell som kan representera en datatyp. T.ex schackbräde för datatypen fält.
•
Struktur hos dataobjekt
Det man har kvar om man bortser från alla elementvärden.
•
Informell specifikation av en gränsyta
Informell beskrivning av operationernas funktion.
•
Beräkningsbar
En funktion är beräkningsbar om och endast om det finns någon turingmaskin som löser och
beräknar funktionen. En turingmaskin är en tänkt, abstrakt maskin med en begränsad
repertoar av operationer till sitt förfogande.
•
(O-)hanterlig ((in-)tractable)
Kan inte lösas praktiskt tex O(2^n), O(n^n). Faktorisera tal till primtal.
•
Hashfunktion
En hashfunktion avbildar en indextyp A till en mindre indextyp B, till exempel strängar till
heltal
•
Fyllnadsgrad
Andel upptagna platser i en statisk datatyp.
•
Position
•
Index
Referens till en position
•
Element
Har en position och ett värde.
•
Elementvärde
Värdet på ett element
Egenskaper/principer
•
FIFO (first-in-first-out).
•
LIFO (last-in-first-out).
•
Komplett träd
Ofta bra balans, fyller på trädet från vänster till höger, en nivå i taget.
•
Fullt träd
Ofta dålig balans, varje nod är antingen ett löv eller har två barn.
•
Lövnod
En nod som inte har några barn
•
Rotnod
Toppen av trädet, ursprungsnoden.
•
Sammanhängande graf
Varje nod har en väg till varje annan nod. Om antalet bågar <antal noder -1 är grafen inte
sammanhängande.
Attribut för datatyper
•
Abstrakt datatyp
Datatyp som endast definieras via sin gränsyta. En term som används när man beskriver,
diskuterar eller använder en datatyp utan att ta hänsyn till om eller hur den är realiserad i ett
programspråk/hårdvara.
•
Fysisk datatyp
En datatyp som finns tillgänglig i en given maskinvara eller programspråk.
Int, float, char
•
Enkel datatyp
En datatyp vars objekt inte består av element som i sin tur är datatypsobjekt. Tex heltal.
•
Konstruerad datatyp
En datatyp där man beskrivit både representationen för objekten och utförandet av
operationerna.
•
Sammansatt datatyp
En datatyp vars objekt består av element som i sin tur är datatypsobjekt. Elementen är
organiserade på ett bestämt sätt. Tex lista av heltal.
•
Implementerad datatyp
En datatyp som är komplett konstruerad från grunden där grunden är fysiska datatyper och
klar att användas i ett program.
•
Homogen vs. heterogen datatyp
Homogen – en sammansatt datatyp där elementen är av en och samma datatyp. Fält och Lista.
Heterogen – inte samma datatyp
•
Dynamisk vs. statisk datatyp
För en statisk datatyp kan storleken inte ändras efter den bestäms (vid ex konstruktion). För
en dynamisk datatyp kan storleken förändras med operationer.
•
Sorterad vs. ordnad datatyp
Ordnad innebär att det finns en viss ordning i datatypen, ett förstaelement, ett andra element
osv. Inbördes ordning. Exempelvis: stack lista osv. Tabell, mängd är ej ordnade.
I en sorterad datatyp bestäms ordningen av elementens värden. De strukturförändrande
operationerna i gränsytan upprätthåller en sorteringsordning vid operationer.
•
Riktad datatyp
Det finns en riktning, till exempel att man bara kan traversera framåt.
•
Hierarkiskt ordnad
Pyramid? Strikt partiell ordning med linjärt ordnade förfäder samt ett minimum.
Komplexitetsanalys
•
Asymptotisk komplexitetsanalys (prio 1)
Räkna operationer, kom fram till en funktion T(n) baserad på operationerna. Hitta sedan C
och n0. C hittas med lim n->oändligheten T(n)/g(n) +1. Finn n där T(n)<=ng(n) börjar gälla.
Gör detta genom att sätta upp olikheten och lösa för n. Det kan då sägas att T(n) är O(g(n))
med c=.. och n0=…
•
Förenklad asymptotisk komplexitetsanalys
En så kallad grovanalys av koden, nästlade loopar räknas. Ingnorera allt förutom
dominerande termer.
•
Experimentell komplexitetsanalys
Testkörningar som mäter tiden det tar för operationen. Implementera algoritmen och ta tid.
•
Absolut komplexitet
Ett idealiserat mått på tidskomplexiteten i en fullständig implementation. Tittar under ytan.
T(n).
Antag att vi har en datatyp ADT1 som är skapad med hjälp av en annan datatyp ADT2. Hur
benämner man komplexiteten när man inte bara tittar på "ytan" och ser hur många ADT2operationer som behövs i en ADT1-operation utan även undersöker komplexiteten hos
ADT2-operationerna och komplexiteten hos de ADT-operationer de eventuellt bygger på? –
Absolut komplexitet.
•
Relativ komplexitet
Komplexitet beräknad i termer av en given abstrakt datatyps operationer, betraktade som
elementära operationer. Tittar bara på ytan. Räknar operationer.
Antag att vi har en datatyp ADT1 som är skapad med hjälp av en annan datatyp ADT2. Hur
benämner man komplexiteten när man enbart tittar på "ytan" och ser hur många ADT2operationer som behövs i en ADT1-operation? – Relativ komplexitet
•
Definitionen av stora Ordo
Vi definierar T(n) att vara O(g(n)) (“stort ordo av g av n”) om och endast om det existerar
konstanter n0, c > 0 sådana att
|T(n)|≤cg(n), ∀n ≥n0
Operationstyper
Konstruktorer – skapar och bygger upp objekt. Finns grundkonstruktorer, konstruktorer som
vidareutvecklar objekt och konstruktorer som kombinerar objekt. Exempel är Empty, create,
list-insert, array-setvalue, stack-push, set-union.
Inspektorer – används för att undersöka ett objekts inre på något sätt. Exempel är: inpectvalue, lookup, stack-top, set-choose, isempty, hasValue, set-memberof, has-left-child.
Modifikatorer – ändrar ett objekts struktur och /eller elementvärden. Ex: array-set-value,
table-remove, stack-pop, stack-push, set-insert, set-remove.
Navigatorer – används för att ta sig fram genom objektets struktur. Förflyttningar eller
traverseringar. Ex: list-first, list-end, list-next, list-previous, left-child.
Komparatorer – jämför objekt av den aktuella typen med varandra. Ex: equal, set-subset.
Grundläggande problemlösningsstrategier
Brute force - Algoritm som testar alla möjliga kombinationer. Att tex testa 0000, 0001 …
9999 för att låsa upp en telefon. Rättfram ansats där man utgår direkt från problemställningen
och de definitioner som finns där.
Greedy algoritm - ta det, för tillfället, bästa alternativet. I varje steg titta på alla möjliga steg
och välja den för tillfället bästa.
Divide and conquer algoritm - Dela upp i mindre delar och löser rekursivt. Sen gör man en
slutlösning för delarna. Söndra: dela upp problemet i flera delar som löses rekursivt. Härska:
skapa slutlösning med hjälp av de andra.
Dynamisk programmering – använder lite minne för att undvika att lösa samma delproblem
flera gånger. Håller reda på redan kända lösningar. Ex. huffmankodning
Metoder att traversera
Bredden-först
Man undersöker en nivå i taget, med början i roten, sedan rotens barn, därefter rotens
barnbarn osv - tills alla noder undersökts. En Kö används för att hålla reda på noder man stött
på men vars barn man inte undersökt.
Djupet-först:
Man följer varje gren i trädet från roten ut till lövet. Så länge man kan gå djupare till en
obesökt nod fortsätter man nedåt. Stack används för att hålla reda på vägen från roten till den
nod man undersöker.
Preorder
Man besöker först (därav pre) roten, sedan traverseras vart och ett av delträden också i
preorder.
Inorder
Besöker först det första delträdet i (i ordning) inorder, sedan roten och sist resten av delträden
i inorder.
Postorder
Besöker vart och ett av delträden i postorder - efteråt besöks roten.
Kunna gränsytan utantill
Ni ska kunna den informella specifikationen utantill, med namn, (in- och ut-) parametrar och
beskrivning i ord av hur den fungerar. Ni behöver inte kunna den formella specifikationen.
Lista:
Empty() → tom lista
Insert(val, pos, list) → sätter in efter pos, returnerar positionen för val. Ej def för sista pos
Isempty(list) → Bool
Inspect(pos, list) → returnerar värdet på pos, ej def för sista pos
First(list) → pos
End(list) → pos
Next(pos, list) → pos efter pos
Previous(pos, list) → pos före pos
Remove(pos, list) → returnerar nya pos för elementet efter borttagna värdet.
Riktad lista
Empty()
Insert(val, pos, list)
Isempty(list)
Inspect(pos, list)
First(list)
Isend(pos, list) → Bool
Next(pos, list)
Remove(pos, list)
Stack
s-stack, v-value
Empty() → tom stack
Isempty(s) → Bool
Push(v, s) – lägger v överst
Pop(s) – tar bort översta elementet
Top(s) → returnerar värdet överst
Kö
q-queue, v-value
Empty() → tom lista
Isempty(q) → bool
Front(q) → värdet på första elementet
Enqueue(v, q) – sätter in v sist i kön
Dequeue(v, q) – tar bort första elementet.
Känna till funktionen för
Ni ska veta hur nedanstående datatyper fungerar, men inte det exakta innehållet i deras
gränsyta:
Länk
Enkel datatyp, referera till ett annat objekt. Pekare.
n-Cell:
En tippel av ett värde och ett fixt antal länkar som refererar till cellen.
Tabell
En ändlig avbildning av argument på värden. Uppslagsbok, nycke och värden.
Array/Fält
Statisk datatyp. Index. Homogen datatyp.
Prioritetskö
Vanliga köer bevarar tidsordningen, medan en prioritetskö används när man vill välja någon
annan ordning på elementen.
Har en grundmängd vars mängd ordnas av en prioritetsordning. Stack och kö är specialfall av
prioritetskö. De har speciala prioritetsordningar. Kö: FIFO, prioritet alltid falsk. Stack: LIFO
prioritet alltid sann (läggs överst i stacken).
Hashtabell
Data sparas tillsammans med en nyckel. Positionen i strukturen beräknas med en
hashfunktion.
Sluten hashning – linjär eller kvadratisk teknik
Öppen hashning – hashvärdena läggs in i en tabell i stället (lista av listor). I lista nummer i
ligger alla element med hashvärde i.
Binärt sökträd
Sorterat träd där vänster barn alltid är mindre än förälder, medan höger alltid är större.
Insättning börjar i roten, sedan letas platsen där värdet passar in upp. Alltså görs jämförelser
om> rot, då fortsätt i höger delträd, annars vänster. Fortsätt så tills rätt plats är hittad.
Sökning i binärt sökträd sker genom att det sökta värdet jämförs med den aktuella nodens
etikett, om inte lika, sker sökning rekursivt nedåt i vänster eller höger delträd allteftersom det
sökta värdet går före respektive efter i sorteringordningen.
Borttagning av noder i binära sökträd:
Lövnod – bara att ta bort
Nod mitt i:
Om noden bara har ett delträd, flyya upp det.
Om noden har två delträd (både höger och vänster) ersätt noden med noden med minsta
värdet i höger delträd, alternativt noden med störst värde i vänster delträd.
Lexikon
Förenklad variant av mängd. Används för att hålla rätt på en samling objekt: sätta in, ta bort
och undersöka medlemskap. Som en tabell utan tabellvärden.
Träd
Noder som är hierarkiskt ordnade genom en förfäder-relation som har ett minimielement, en
rot. Ordnat träd – barnen bildar en lista, regemente. Oordnat träd – barnen bildar en mängd.
Höjden för en nod = ”hur många steg behöver vi gå tills vi når längst ner i trädet” Nivån – 1
Djupet hos en nod är antalet bågar från noden till roten. Homogen datatyp.
Binärt träd
Ett binärt träd kan ha högst två barn. Höger och vänsterbarn är inte samma. Kan jämföras
med en antavla över förfäder med yngst i roten.
Heap
Binärt partiellt sorterat träd där borttagning endast kan göras i roten. Finns max och min
heap, min har minsta elementet i roten. Insättning sker på nedersta nivån på första lediga
platsen till vänster. Elementet flyttas sedan för att passa in i ordningen. Borttagning sker i
roten, och noden längst ner till höger flyttas till rotens plats för att sedan flyttas runt till rätt
plats i ordningen.
Trie
En variant av ett träd. Barnen är organiserade som tabellvärden i en tabell som tillhör noden.
Noderna har namn.
Mängd
En mängd är en fullständigt oordnad samling element eller medlemmar som alla är av en
bestämd datatyp.
Graf
En variant av binär relation på en mängd. Består av en mängd noder och bågar. Gradtalet =
Antalet bågar till grannar (inklusive sig själv). En ögla räknas 2 ggr.
I riktade grafer är ingradtalet = antalet bågar som går till noden. Utgradtalet = antalet bågar
som startar i noden och går till en annan nod.
Komplett graf – alla noder är grannar till alla andra.
Om antalet bågar < antal noder -1 är grafen inte sammanhängande.
Sortering
Stabil sortering
Den inbördes relationen mellan två objekt med samma
nyckel bibehålls vid sortering.
Sorteringsalgoritmer
Bubblesort O(n^2) - stabil
Algoritmen innebär att det område av en lista som skall sorteras gås igenom upprepade
gånger och parvisa jämförelser görs av intilliggande element. Om elementen är i fel ordning
kastas elementens ordning om. Efter varje genomgång av ett område kommer det sista talet
att ha hamnat på rätt plats. Vid nästa genomgång reduceras därför det område som gås
igenom med ett. Efter hand som sorteringen fortlöper kommer den korrekt sorterade delen i
botten av listan att växa med ett element per genomgång av den ännu osorterade delen av
listan och de ännu osorterade elementen "bubblar" uppåt, därav namnet på
sorteringsalgoritmen.
Insertion sort O(n^2) - stabil
Väljer ett element och jämför mot de andra för att se var i sorteringen det ska sättas in.
1. Jämför det nya talet med det sista talet i listan
2. Om det nya är större, lägg det sist i listan
3. Flytta annars det sista talet ett steg bakåt och jämför igen
4. Flytta så många tal som behövs ett steg bakåt för att sätta in det nya talet på rätt plats
5. Upprepa för varje nytt tal
Selection sort O(n^2) - instabil
Går igenom listan och plockar ut det minsta elementet, upprepar och sätter in i en ny lista
som blir den sorterade listan.
Mergesort o(nlog(n)) - stabil
Merge Sort-algoritmen är av typen söndra och härska, och har konceptuellt följande steg för
att sortera en lista med storlek n:
1. Dela upp listan i n lika stora dellistor (alla med längd 1)
2. Slå samman dellistorna parvis i sorterad ordning
3. Upprepa steg två, tills det bara finns en lista kvar
Den slutgiltiga listan är original-listan i sorterad ordning.
Quicksort O(nlog(n)) - instabil
Quicksortalgoritmen är av typen söndra och härska, och består av följande steg:
1. Välj ett element, kallat pivot-element, ur listan.
2. Ordna om listan så att alla element som är mindre eller lika med pivot-elementet
kommer före detta, och så att alla element som är större än pivot-elementet kommer
efter detta. Pivot-elementet har nu fått sin rätta plats.
3. Sortera rekursivt de två dellistorna, det vill säga med just denna algoritm.
Val av pivot är kritiskt! Man vill ha ett som är i mitten av sorteringsordningen eftersom
listan delas in i två listor, en större och en mindre än pivot. Om man exempelvis väljer
minst elementet kommer komplexiteten öka till O(n^2). Det blir så som instickssortering
eller urvalssortering vid sned fördelning.
Pivot-element
Elementet som väljs först av en algoritm.
För en del sorteringsalgoritmer finns två versionerbeskrivna:
(En version som tar en in-lista och bygger upp en ut-lista.
En version som jobbar direkt i in-listan, s.k. in-place.
För algoritmer som finns i bägge versionerna räcker det med att ni kan en av versionerna.
Bubblesort är in-place, övriga är "en lista in, en lista ut". Dessutom ska ni kunna använda en
heap och ett binärt sökträd för att sortera. Ni ska kunna avgöra/veta vilka sorteringsalgoritmer
som är stabila.)
Sortering med en heap - instabil
Heapsort får man genom att först stoppa in den osorterade sekvensen i en heap och sedan ta
ut alla element igen. O(nlogn)
Sortering med binärt sökträd
Sortering med binärt sökträd görs genom att stoppa in den osorterade sekvensen i ett BST och
sedan göra en in-order traversering av det.
Sökning
Linjärsökning
O(n), Starta från början och sök tills elementet hittat eller sekvensen slut.
Elementet finns: i medel gå igenom halva listan
Elementet finns inte: i medel gå igenom hela listan
Om listan är sorterad och elementet saknas: räcker att i medel leta genom halva listan.
Binärsökning
Om sekvensen har index (tex i en array eller numrerad lista) kan man söka binärt. Successiv
halvering av sökintervallet. Jämför med elementet närmast mitten i intervallet. Om likhet –
klart! Om det sökta värdet kommer före i sorteringsordningen fortsätt sökningen rekursivt i
det vänstra delintervallet. Om det kommer efter i sorteringsordningen fortsätt sökningen
rekursivt i det högra delintervallet. Vi får värsta-falls och medelkomplexitet O(logn).
Djupet-först sökning
Finns tre olika. Pre-, in-, och postorder.
Bredden-först sökning
Uppifrån vänster till höger, går igenom en hel nivå innan nästa.
Övriga algoritmer
Floyd
Bygger på matrisrepresentation av en graf, denna innehåller vikterna på bågarna mellan
noderna. Vill hitta kortaste vägen genom grafen. Från alla noder till alla noder.
Algoritmen tar fram avståndet mellan två noder, för att sedan jämföra det med andra avstånd
mellan samma noder via andra noder. Den sparar sedan kortaste vägen.
Dijkstra
Att finna kortaste vägen från en nod till alla andra noder. Använder en prioritetskö. Fungerar
enbart på grafer med positiva vikter.
Färgar noderna allt eftersom
Man kollar på en nod, tar ut alla grannar, sparar avståndet till alla dessa och lägger bågarna i
en prioritetskö. Sedan plockar man ut första ur kön, alltså närmsta granne, tar fram dens
grannar och kollar alla avstånd. Om en granne redan är besökt, kollas om det nya avståndet
via den aktuella noden är kortare, i så fall uppdateras avståndet med det nya och läggs in i
kön.
Prim
Navigeringsorienterad specifikation. Söker ett uppspännande träd i grafen med minsta
möjliga totala längd. Går ut på att bygga upp ett allt större träd som till slut spänner upp
grafen. Man väljer i varje steg en båge med minimal vikt. Använd en prioritetskö för att hålla
reda på vilka bågar som kan vara aktuella.
Kruskal
Utgå från en prioritetskö av alla bådar. Mängdorienterad specifikation.
Huffman (bygga optimalt Trie, kodning, dekodning)
Koder för sekvenser
Gör en tabell över frekvenserna, välj sedan de två minsta frekvenserna och sätt ihop, summan
står i föräldernoden. Kolla på nästa nod, vilken kan den kopplas ihop med för att få lägsta
siffran? Är det den till vänster eller toppen av trädet till höger? Om det ger samma så välj det
trädet som ger lägst höjd. Lägg sedan till nästa frekvens till det träd som har topnod där
summan genererar minsta värdet.
Pseudokod – programkonstruktion
 används för tilldelning
= används för likhetsrelation
Funktionsdeklaration: Algoritm name(param1, param2)
Under Algoritm name(param1, param2) ska in-, och output specificeras.
Input: beskrivning av parametrar
Output: beskrivning av returvärden
Minsta uppspännande träd
Man söker ett uppspännande träd med minsta möjliga totala längd (höjd). Det minsta
uppspännande trädet i en graf är en samling av kanter som kopplar ihop alla noder i grafen.
Denna samling av kanter har tillsammans den minsta möjliga vikten. Alla noder måste alltså
ingå.
Navigerings- och mängdorienterad specifikation
Navigering – bygger på grannarna till en nod. En grannskapsmängd. Ger mer effektiva
navigeringsoperationer. Prims och dijkstras.
Mängd – bygger på en mängd av bågar mellan noder. Kruskals och floyds.
Vilka problem kan uppstå när man använder linjär teknik?
Ett stort problem kan bli den sk. Klustringen som kan uppkomma,
dvs att delar av hashtabellen fylls igen och kan leda till en lång
kedja med kollisioner innan tom plats påträffas och söktiderna
blir mer ordo(n) än den ordo(1) som man strävar efter.
Val av mod vid sluten hashning görs utifrån att fyllnadsgraden inte bör vara mer än 75% och
ett primtal för att få bättre spridning. Om vi då har 13 element passar mod 17 exempelvis.
Vid öppe hashning räcker det att ha mod som är halva antalet element.
Download