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

Relevanta dokument
Tentamen Datastrukturer (DAT037)

Föreläsning 4 Datastrukturer (DAT037)

Tentamen Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT036)

Föreläsning 4 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT037)

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

Tentamen Datastrukturer (DAT036/DAT037/DIT960)

Föreläsning Datastrukturer (DAT037)

Tentamen Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT037)

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning Datastrukturer (DAT036)

Föreläsning 10 Datastrukturer (DAT037)

Föreläsning 9 Datastrukturer (DAT037)

Föreläsning 7 Datastrukturer (DAT037)

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning Datastrukturer (DAT036)

Tentamen Datastrukturer (DAT036)

Föreläsning 11 Datastrukturer (DAT037)

Exempeltenta GruDat 2002/2003

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

Tentamen Datastrukturer, DAT037 (DAT036)

Föreläsning 8 Datastrukturer (DAT037)

Föreläsning 13 Datastrukturer (DAT037)

Dugga Datastrukturer (DAT036)

Lösningsförslag till tentamen Datastrukturer, DAT037,

Föreläsning Datastrukturer (DAT037)

Föreläsning 13 Datastrukturer (DAT037)

Föreläsning 8 Datastrukturer (DAT037)

Tentamen Datastrukturer (DAT036)

Prov i DAT 312: Algoritmer och datastrukturer för systemvetare

Föreläsning 5 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

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

Föreläsning 6 Datastrukturer (DAT037)

Tentamen Datastrukturer D DAT 036/DIT960

Tentamen Datastrukturer D DAT 035/INN960

Föreläsning 6 Datastrukturer (DAT037)

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning.

Tentamen Datastrukturer D DAT 035/INN960 (med mycket kortfattade lösningsförslag)

Tentamen Datastrukturer för D2 DAT 035

Föreläsning 1 Datastrukturer (DAT037)

Tentamen Datastrukturer D DAT 036/INN960

Föreläsning 2 Datastrukturer (DAT037)

Programkonstruktion och. Datastrukturer

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning Datastrukturer (DAT036)

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

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

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

Algoritmer, datastrukturer och komplexitet

Föreläsning 5 Innehåll

Tentamen Datastrukturer D DAT 036/INN960

Tentamen Datastrukturer D DAT 035/INN960

Tentamen i Algoritmer & Datastrukturer i Java

Föreläsning 5: Grafer Del 1

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

Tommy Färnqvist, IDA, Linköpings universitet

DAI2 (TIDAL) + I2 (TKIEK)

Algoritmer, datastrukturer och komplexitet

Tentamen Datastrukturer (DAT036)

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

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

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

Lösningar Datastrukturer TDA

Sökning och sortering

Föreläsning 13 Innehåll

Fredag 10 juni 2016 kl 8 12

Teoretisk del. Facit Tentamen TDDC (6)

Grafer MST Top. sortering Starkt samm. komponenter Kortaste avstånd. Grafalgoritmer 1. Douglas Wikström KTH Stockholm

TDDI16 Datastrukturer och algoritmer. Algoritmanalys

Föreläsning Datastrukturer (DAT036)

Tentamen kl Uppgift 4. Uppgift 5

Föreläsning 3 Datastrukturer (DAT037)

Upplägg. Binära träd. Träd. Binära träd. Binära träd. Antal löv på ett träd. Binära träd (9) Binära sökträd (10.1)

Lösningsförslag till tentamen i EDA690 Algoritmer och Datastrukturer, Helsingborg

ADT Prioritetskö. Föreläsning 13 Innehåll. Prioritetskö vs FIFO-kö. Prioritetskö Exempel på användning. Prioritetsköer och heapar

Teoretisk del. Facit Tentamen TDDC kl (6) 1. (6p) "Snabba frågor" Alla svar motiveras väl.

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Grundläggande datalogi - Övning 4

ADT Prioritetskö. Föreläsning 12 Innehåll. Prioritetskö. Interface för Prioritetskö. Prioritetsköer och heapar

Övningsuppgifter #11, Programkonstruktion och datastrukturer

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

Tentamen i Algoritmer & Datastrukturer i Java

Seminarium 13 Innehåll

Tentamen i Algoritmer & Datastrukturer i Java

TDDB56 DALGOPT Algoritmer och Optimering Tentamen , 8 13

Föreläsning 5: Giriga algoritmer. Kruskals och Prims algoritmer

Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs

Facit Tentamen TDDC kl (6)

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

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

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

Föreläsning 4: Kombinatorisk sökning

Träd Hierarkiska strukturer

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet

Transkript:

Lösningsförslag för tentamen i Datastrukturer (DAT7) från --9 Nils Anders Danielsson. Träd- och köoperationerna har alla tidskomplexiteten O(log s), där s är antalet element i trädet/kön (notera att jämförelser tar konstant tid): t.deletemin: O(log s), där s är antalet element i t. t.insert: O(log s), där s är antalet element i t. q.deletemin: O(log s), där s är antalet element i q. q.insert: O(log s), där s är antalet element i q. Eftersom alla element är olika blir tidskomplexiteten (O( s=n n log s) + O( s= log s)) + O(n) = O(log(n! )) = O(n log n), där termen O(n) härrör från loopadministration: test av loopvillkor m m.. (a) public int size() { int length = ; Node here = first; while (here!= null) { length++; here = here.next; return length;

(b) Låt oss använda en hashtabell för att hålla reda på de noder som vi redan har besökt: public int size() { Set<Node> seen = new HashSet<>(); Node here = first; while (here!= null &&! seen.contains(here)) { seen.add(here); here = here.next; return seen.size(); Om vi antar att hashtabellsoperationerna tar amorterat konstant tid så utförs amorterat konstant arbete per listnod, och amorterat konstant övrigt arbete, och i så fall är algoritmen linjär i listans storlek (Θ(n), där n är storleken).. Använd ett prefixträd. En möjlighet är att använda följande datatyp: -- Invariant: Ingen BitTrie får ha formen -- Node False Empty Empty. data BitTrie = Empty Node Bool BitTrie BitTrie _ ger semantiken av en BitTrie som en mängd av bitsträngar: Empty = Node b l r = { [] b = True { : s s l { : s s r Notera att invarianten medför att t = om och endast om t = Empty. (Det kan bevisas med induktion.) Operationerna kan implementeras på följande sätt: empty: Skapa ett tomt träd (Empty). Tidskomplexitet: O(). insert: Sätt in strängen i trädet. Tidskomplexitet: O(l). Notera att det är lätt att se till att insättningsalgoritmen bevarar invarianten ovan. (För ett exempel på en implementation, se uppgift på tentan från december, men byt ut True mot och False mot.) somememberstartswith: Uppgiften är att avgöra om en given sträng s är ett prefix av någon sträng i trädet. Det kan man göra genom att

söka efter s. Om man stöter på det tomma trädet så är svaret nej, och annars är svaret ja: isprefix :: [Bit] -> BitTrie -> Bool isprefix _ Empty = False isprefix [] _ = True isprefix ( : s) (Node _ l _) = isprefix s l isprefix ( : s) (Node r) = isprefix s r Notera att den här funktionen som värst är linjär i bitsträngens längd (tidskomplexitet: O(l)). Man kan bevisa att funktionen är korrekt, s t. s är ett prefix av s, med strukturell induktion. Betrakta följande fyra uttömmande fall: t = Empty: Här ska man bevisa en ekvivalens mellan två osanna påståenden: False = True s. s är ett prefix av s. s t. s är ett prefix av s. s = [], t Empty: Invarianten ger att t, varför man får att True = True t s t. [] är ett prefix av s. s = : s, t = Node _ l _: Induktionshypotesen ger att isprefix s l = True s l. s är ett prefix av s s t. : s är ett prefix av s. s = : s, t = Node r: Induktionshypotesen ger att isprefix s r = True s r. s är ett prefix av s s t. : s är ett prefix av s.

. Algoritmens steg ( kända noder har heldragna kanter, och nodetiketterna är de bästa kända avstånden): 7 7 Vi får följande lista: [(a, ), (b, ), (d, ), (e, ), (c, )].. (a) i. [,, 8, 79, 7]. ii. [, 8,, 7, 79]. iii. [,, 7, 79, 8]. (b) Mergesort fungerar, givet att en stabil implementation används. Heapsort är vanligtvis inte stabil, i vilket fall algoritmen inte fungerar. Betrakta följande lista: [, ]. I första steget sorterar vi med avseende på sista siffran, och får då [, ]. I andra steget sorterar vi med avseende på första siffran. Vi utgår från arrayen. Första steget i sorteringen är att bygga en maxheap med build-heap-algoritmen. Eftersom trädet som arrayen representerar redan uppfyller heapinvarianten så ligger alla element kvar ( ). Nästa steg är att ta bort heapens översta element r = ( ), sätta heapens sista element överst ( ), bubbla ned det översta elementet ( ), och sätta in r sist i arrayen ( ). Den slutgiltiga listan blir [, ], som inte är sorterad.

. Låt oss anta att noderna är numrerade från till v, och att grafen representeras av grannlistor: en array med storlek v, där position i innehåller en länkad lista med nod is direkta efterföljare. Notera att man kan ta fram en mängd innehållandes alla noder som kan nås från en nod u på följande sätt: utför en djupet först-sökning med början i u, och lägg varje nod som besöks i en från början tom mängd. Om mängden implementeras med en bitarray av storlek v så är tidskomplexiteten O(v + e) (där e är antalet kanter i grafen). Algoritmen: (a) Använd algoritmen ovan för att ta fram en mängd A med noderna som kan nås från a. Tidskomplexitet: O(v + e). (b) Använd algoritmen ovan för att ta fram en mängd B med noderna som kan nås från b. Tidskomplexitet: O(v + e). (c) Beräkna snittet av de två mängderna. Resultatet är en mängd C = A B som innehåller exakt de noder som kan nås från både a och b. Avgör om C är tom, i vilket fall algoritmens svar är nej. Tidskomplexitet: Θ(v). (d) Sortera grafen topologiskt, och notera vilken nod d i C som hamnar tidigast i den topologiska ordningen. Tidskomplexitet: Θ(v + e). (e) Det återstår att avgöra om någon nod c i C har egenskapen att alla andra noder i C kan nås från c. Definitionen av topologisk ordning ger att den enda noden som kan ha den här egenskapen är d. Använd algoritmen ovan för att ta fram en mängd D med noderna som kan nås från d, och avgör om C är en delmängd av D. Om så är fallet så är algoritmens resultat ja, och annars är resultatet nej. Tidskomplexitet: O(v + e). Sammanlagd tidskomplexitet: Θ(v + e). Algoritmen är alltså linjär i grafens storlek, vilket kanske kan anses vara effektivt. Notera dock att algoritmen besöker noder som inte kan nås från a eller b, och plats allokeras dessutom för sådana noder i mängderna. Med lite andra val av datastrukturer och algoritmer (t ex kan hashtabeller användas för att implementera mängder) kan man (givet tillräckligt bra hashfunktioner) konstruera en algoritm med tidskomplexitet Θ(v + e ), där v är antalet noder som kan nås från a och/eller b, och e är totala antalet kanter som lämnar dessa noder. Med en effektiv implementation. Liknande brasklappar gäller för flera andra påståenden i det här lösningsförslaget.