Programmeringsteknik - fördjupningskurs

Storlek: px
Starta visningen från sidan:

Download "Programmeringsteknik - fördjupningskurs"

Transkript

1 Programmeringsteknik - fördjupningskurs David Karlsson 11 april

2 Innehåll 1 Objektorientering 4 2 Kommentering av koden 6 3 Typer av fel Exception Autoboxing - unboxing 7 5 Generik 8 6 Java Collections Framework Iteratorer Implementation av iterator foreach Söka efter objekt i en collection Sortera objekt i en collection Listor Stackar Köer Implementering av köer och stackar Stack genom att delegera till LinkedList Egen klass för stack och kö Algoritmers effektivitet, tidskomplexitet Ordonotation Asymptotisk tidskomplexitet Olika tidskomplexiteter Worst case och Average case Rekursion Rekursiv metod Rekursiv lista Samband mellan rekursion och induktion Induktion för att verifiera rekursion Divide and conquer approach Val av lösning Grafiska användargränssnitt Träd Terminologi Binära träd Traversering

3 11 Binära sökträd Sökning i binära sökträd Implementering av binärt sökträd Insättning: Borttagning: Tidskomplexitet hos binära sökträd, en funktion av höjden Garanterat minimal höjd Problematik: insättningsordning Algoritmer för att hålla binära sökträd balanserade (AVL-träd) Detektera obalans Kostnad för att balansera ett träd Set Sorted Set Set klasser TreeSet Interfacet Comparator Map Map klasser Några metoder i Map Implementera Map med sökträd Hashtabeller Sluten hashtabell Öppen hashtabell (separate chaining) Metoden hashcode() Sökning i öppen hashtabell Använda HashMap Använda HashSet Prioritetsköer PriorityQueue Implementering av prioritetskö - tidskomplexiteter Heapar Heap i vektor Insättning Tidskomplexitet för insättning Peek Poll Tidskomplexitet för poll Heap av osorterad samling Hjälpmetoden Heapify Heapifys tidskomplexitet Heapify implementering Sortering med prioritetskö

4 16.4 Heapsort Alternativa prioritetsköer Sortering Urvalssortering Insättningssortering Insättningssortering implementerad Mergesort Mergesort implementerad Tidskomplexitet Quicksort Algoritm för quicksort Implementering Tidskomplexitet Val av pivotelement Förbättringar Sorterings algoritmer i sammanfattning Bevis: 60 Detta häfte innehåller en sammanfattning av allt som gåtts igenom på föreläsningarna i kursen EDAA01, vid LTH. Kursen heter: Programmeringsfördjupning, men borde fortfarande gå under namnet Algoritmer och datastrukturer. 1 Objektorientering Java är ett objekt orienterat programmeringsspråk. Det innebär att lösningarna och problemen struktureras upp som objekt med egenskaper och metoder. Objektbeskrivningen är abstrakt, dvs enbart objektegenskaper som är viktiga och relevanta för vårt problem tas med. Definition 1 (Abstrakt datatyp) En abstrakt datatyp(adt) är en specifikation av en klass eller ett interface. En klass är en implementation av en ADT. Exempel Komplexa tal En abstrakt datatyp kan till exempel vara en modell för komplexa tal innehållande funktioner för att hämta real- respektive imaginärdel samt addera mm. Motivation för abstrakta datatyper kan vara: Man kan göra ett klassbibliotek. Implementeringen kan ändras utan att resten av koden påverkas. Koden kan utnyttjas för flera problem. Koden kan testas sepparat. 4

5 Definition 2 (Interface) För att specifiera en abstrakt datatyp används ofta interface. Ett interface är ett gränssnitt innehållande alla metoddeklarationer för datatypen, det vill säga tomma metoder. Interfacet implementeras sedan av en eller flera klasser där även metoderna implementeras. Interfacet är således en specifikation på vad en klass ska innehålla. På så vis kan utvecklarna ta fram andra delar av programmet innan interfacen implementerats, då de vet vad de kommer innehålla. En klass kan implementera flera interface och ett interface kan implementeras av flera klasser. public class MyComplexNumber2 implements ComplexNumber, C l o n e a b l e { // Implementerar a l l a metoder i i n t e r f a c e n ComplexNumber och C l o n e a b l e Listing 1: Exempel implementera flera interface 5

6 2 Kommentering av koden För att skapa struktur i koden och underlätta för javadocs används pre- och postconditions. Preconditions beskriver vilka villkor som måste uppfyllas innan en metod exekveras. Postconditions beskriver hur exekveringen påverkar objektet. p u b l i c c l a s s BankAccount { p r i v a t e i n t balance ;... / Deposits the s p e c i f i e d amount. pre : The s p e c i f i e d amount i s >= 0 post : The s p e c i f i e d amount i s added to n The amount to d e p o s i t / p u b l i c void d e p o s i t ( i n t n ) { balance = balance + n ;... 3 Typer av fel Syntaxfel: Koden som skrivits följer inte java syntaxreglerna. Syntaxfel kan vara en glömd parentes eller en variabel som används innan deklarerats etc. Exekveringsfel: Koden som exekveras ger ett fel. Det kan tillexempel vara en index variabel som blir för stor för en vektor, nollpekare eller liknande. Logiska fel: Programmet körs som det ska men producerar ett felaktigt resultat. Tillexempel en implementation av ett digitalt filter som inte filterar. 3.1 Exception När ett exekveringsfel uppstår genereras ett undantag, exception. I vanliga fall avslutas då programmet och ett meddelande skrivs ut i java terminalen där felets typ beskrivs samt en stacktrace presenteras. Man kan undvika att programmet avbryts om man själv väljer att hantera ett exception. Detta görs med hjälp av catch-block. Exceptions kan vara checked eller unchecked: Checked exception: ex file not found. Unchecked exception: felet beror på programmeraren, t ex nullpointer eller index out of bounds. När man fångat en exception kan man rätta till felet. Det kan tillexempel vara ett fel av typen file not foundsom uppstår när man försöker öppna en fil som inte finns. I catch blocket kan man då presentera en dialog för användaren där man kan leta fram filen manuellt etc. try { // kod som kan g e n e rera e x c e p t i o n catch ( ExceptionClass1 e1 ) { // kod f ö r a t t hantera e x c e p t i o n av typen ExceptionClass1 6

7 catch ( ExceptionClass2 e2 ) { // kod f ö r a t t hantera e x c e p t i o n av typen ExceptionClass2 f i n a l l y { // kod som u t f ö r s e f t e r try b l o c k e t e l l e r e f t e r catch b l o c k e t Man kan även generera exceptions själv med hjälp av throw: throw new IllegalArgumentException (" n < 0 " ) ; Koden ovan genererar en Illegal argument exception med meddelandet n < 0. Egna exception-typer kan skapas genom att man skriver egna exception klasser som extensions till ex. exception klassen eller runtime exception klassen. p u b l i c c l a s s S p e l l E x c e p t i o n extends Exception {... Kasta exceptions vidare till anropande funktion: p u b l i c Scanner createscanner ( S t r i n g filename ) throws FileNotFoundException { // Här g e n e r e r a s e x c e p t i o n om f i l e n i n t e går a t t öppna Scanner scan = new Scanner (new F i l e ( filename ) ) ; r eturn scan ; På detta visa behöver inte metoden hantera exceptions utan detta överlåts helt enkelt till den anropande koden. 4 Autoboxing - unboxing De primitiva datatyperna: boolean, char, int, mfl. är inte subtyper av klassen Object, och kan således inte användas som object-typen i listor och liknande (Collections-typer). Då måste värdena konverteras till object-typ. Motsvarande object-typ för int är Integer, char är Character, boolean är Boolean osv. Från och med Java 1.5 sköts typkonverteringen automatiskt t ex: I n t e g e r i = new I n t e g e r ( 1 2 ) ; i = i + 100; // Konverteras automatiskt t i l l I n t e g e r. i n t j =10; myarraylist. add ( j ) ; // Konverteras automatiskt t i l l I n t e g e r. Unboxing : Integer = int (1) Boxing : int = Integer (2) 7

8 5 Generik Generik innebär att man implementerar generella klasser eller interface som kan användas till flera olika objekttyper. Tidigare gav man metoderna parametrar av typen object för då kunde alla subtyper till object användas. Numera kan man använda typparametrar när man definerar en klass. Därefter typecastar man klassens instantiering till den typ man vill ha genom att sätta typparametrarna. p u b l i c c l a s s ArrayList<E> { ArrayList<Integer > mylist = new ArrayList<Integer >(); Fördelen med det senare sättet är att kompilatorn nu kan upptäcka typfel. Om man har en lista med < Integer > och försöker lägga till en sträng uppstår ett fel då listan är deklarerad för att innehålla enbart Integerobjekt. Alla operationer är dock inte castade, tex ArrayList<E> innehåller metoderna: p u b l i c boolean c o n t a i n s ( Object x ) ; p u b l i c boolean remove ( Object x ) ; Detta för att användare som inte känner till typen ska kunna anropa metoderna med true/false som svar beroende på om objekten hittas. En generisk klass kan även ha flera typparametrar: p u b l i c c l a s s Pair<K, V> { p r i v a t e K key ; p r i v a t e V value ; p u b l i c Pair (K key, V value ) { t h i s. key = key ; t h i s. value = value ; p u b l i c V getvalue ( ) { r eturn value ; p u b l i c void setvalue (V val ) { value = val ;... Pair<String, Integer > p a i r = new Pair<String, Integer >("June ", 3 0 ) ; i n t nbrdays = p a i r. getvalue ( ) ; Även nästlade typparametrar är tillåtna: p u b l i c i n t e r f a c e Set<E> { boolean add (E x ) ; i n t s i z e ( ) ; boolean c o n t a i n s ( Object x ) ; 8

9 Set<Set<String >> // n ä s t l i n g Typparametrarna kan även begränsas. Om man till exempel vill vara säker på att klassen i typparametern implementerar comparable kan man skriva: p u b l i c c l a s s ASortedCollection <E extends Comparable<E>> Vi kan därmed säkert använda metoden compareto på objekt av typen E i implementeringen av ASortedCollection. Varning 1 Parametern till en generisk klass får inte vara en primitiv: SomeClass<int> c =... // ej möjligt! Typvariabler kan inte användas för att skapa objekt: E x = new E(); // Fel! Typparametrar kan inte användas för att överlagra metoder: public class MyClass<T,U> public void p(t x)... public void p(u x)... // Fel!... 6 Java Collections Framework Java collections är ett ramverk av abstrakta klasser, interface och konkreta klasser för samlingar av element, så som listor, köer mm. Java collections är hierarkiskt uppbyggt kring interfacet Collection. Se figur 1. Grunden i interfacet collection är metoderna: i n t e r f a c e C o l l e c t i o n <E> { boolean add (E x ) ; boolean c o n t a i n s ( Object x ) ; boolean remove ( Object x ) ; boolean isempty ( ) ; i n t s i z e ( ) ;... Några klasser i java collections, som implementerats med respektive interface, visas nedan i 3. Queue = LinkedList, P riorityqueue List = ArrayList, LinkedList Set = HashSet SortedSet = T reeset Map = HashMap SortedMap = T reemap (3) 9

10 <<Interface>> SortedSet <<Interface>> SortedMap <<Interface>> Set <<Interface>> List <<Interface>> Queue <<Interface>> Map <<Interface>> Collection Figur 1: Java collections framework hierarkin av interface. De olika interfacen i collections skiljer sig enligt: Collection : En samling av element, där dubbletter tillåts. Queue : En samling av element som utgör en kö. List : En samling element där dubbletter tillåts och där positionering är mo?jlig (första, sista, element på plats i,...). Set : En samling element där dubbletter är förbjudna. SortedSet : Som Set men med krav att elementen går att jämföra. Map : en samling av element, där varje element har en en nyckel och ett värde (jfr. lexikon) SortedMap : som Map men med krav att nycklarna går att jämföra. 6.1 Iteratorer p u b l i c i n t e r f a c e I t e r a t o r <E> { / Returns true i f the i t e r a t i o n has more elements. / boolean hasnext ( ) ; / Returns the next element in the i t e r a t i o n. / E next ( ) ; / Removes from the underlying c o l l e c t i o n the l a s t element returned by the i t e r 10

11 void remove ( ) ; Interfacet collection ärver från interfacet iterable, innehållande funktionen iterator som returnerar ett iteratorobjekt (se interface ovan). Iteratorobjektet används när man behöver gå igenom objekten i en collection. T ex en ArrayList med strängar som man vill jämföra. För att iterera objekten måste Iterator instantieras enligt nedan, där funktionen iterator används för att skapa en iterator tillhörande plist. //En samling med Person o b j e kt d e f i n i e r a s och f y l l s : ArrayList<Person> p L i s t = new ArrayList<Person >();... // I t e r a t o r n i n s t a n t i e r a s. I t e r a t o r <Person> i t r = p L i s t. i t e r a t o r ( ) ; while ( i t r. hasnext ( ) ) { Person p = i t r. next ( ) ; // behandla v a r j e Person objekt Implementation av iterator p u b l i c c l a s s ArrayColleciton <E> implements C o l l e c t i o n <E> { p r i v a t e E [ ] t h e C o l l e c t i o n ; p r i v a t e i n t s i z e ; // Konstruktor... // Metoder... p u b l i c I t e r a t o r <E> i t e r a t o r ( ) { r eturn new A r r a y I t e r a t o r ( ) ; p r i v a t e c l a s s A r r a y I t e r a t o r implements I t e r a t o r <E> { p r i v a t e i n t pos ; p r i v a t e A r r a y I t e r a t o r ( ) { pos = 0 ; p u b l i c boolean hasnext ( ) { r eturn pos < s i z e ; p u b l i c E next ( ) { i f ( hasnext ( ) ) { E item = t h e C o l l e c t i o n [ pos ] ; pos++; return item ; 11

12 e l s e { throw new NoSuchElementException ( ) ; p u b l i c void remove ( ) { throw new UnsupportedOperationException ( ) ; Ovan visas en klass som implementerar en förenklad version av Iterator (en korrekt implementering måste upptäcka om samlingen modifierats mellan next anropen och då generera en exception). Iterator har placerats som en inre klass och eftersom iterator funktionen i den överliggande klassen instantierar iteratorn kan iteratorklassen även vara privat. 6.3 foreach Ett enkelt sätt att iterera över collections och slippa skriva en instantiering av iteratorn varje gång är att använda sig av foreach. En foreach fungerar både för objekt av typ som implementerar Iterable och för vektorer. Nedan visas ett enkelt exempel där personlist kan vara av valfri typ med stöd för foreach. f o r ( Customer c : p e r s o n L i s t ){ System. out. p r i n t l n ( c. getname ( ) ) ; Begränsningen med foreach är dels att den inte tillåter användaren att använda iteratorn i koden, till exempel när man behöver ta bort element ur en lista: I t e r a t o r <Person> i t r = p L i s t. i t e r a t o r ( ) ; while ( i t r. hasnext ( ) ) { i f ( i t r. next ( ). e q u a l s ( x ) ) { i t r. remove ( ) ; En annan begränsning uppstår då man vill iterera parallellt över flera samlingar, då får man använda iteratorer, se nedan. Däremot kan man göra nästlade foreach-loopar, d.v.s en foreach innuti en annan. ArrayList<Person> l i s t 1, l i s t 2 ;... I t e r a t o r <Person> i t r 1 = l i s t 1. i t e r a t o r ( ) ; I t e r a t o r <Person> i t r 2 = l i s t 2. i t e r a t o r ( ) ; while ( i t r 1. hasnext ( ) && i t r 2. hasnext ( ) ) { System. out. p r i n t l n ( i t r 1. next ( ) + " " + i t r 2. next ( ) ) ; 12

13 6.4 Söka efter objekt i en collection Skriver man en klass Personsom innehåller ex. namn och personnummer som man sedan ska lägga i någon form av collection så måste man utvidga equals metoden, från början finns equals i superklassen object och fungerar så att den jämför om objekten är identiska. För att den ska fungera som vi vill på vår Person klass måste vi överskugga equals i object klassen med en likadan metod i Person. Som jämför namn och id-number, dvs innehållet i objekten. I implementationen nedan jämförs endast personnummer: p u b l i c boolean e q u a l s ( Object obj ) { i f ( obj i n s t a n c e o f Person ) { r eturn idnbr == ( ( Person ) obj ). idnbr ; e l s e { r eturn f a l s e ; En bättre implementation tillåter bara att objekt av samma typ jämförs. Detta görs med hjälp av metoden getclass: p u b l i c boolean e q u a l s ( Object obj ) { i f ( obj == t h i s ) { r eturn true ; i f ( obj == n u l l ) { r eturn f a l s e ; i f ( t h i s. g e t C l a s s ( )!= obj. g e t C l a s s ( ) ) { r eturn f a l s e ; r eturn idnbr == ( ( Person ) obj ). idnbr ; 6.5 Sortera objekt i en collection För att kunna sortera innehållet i en collection måste jämförelsen utvidgas från att finna likhet till att jämföra objekten. Till detta ändamål finns interfacet Comparable < T > med funktionen compareto(t x) som returnerar ett nummer, ett negativt tal betyde mindre än, ett positivt tal betyder större än och noll betyder lika. Person klassen ovan skulle kunna utvidgas så det implementerar comparable enligt: p u b l i c c l a s s Person implements Comparable<Person> {... p u b l i c i n t compareto ( Person x ) { r eturn idnbr x. idnbr ; 13

14 Då kan och bör, för att ge konsistenta resultat, även equals metoden ersättas med: p u b l i c boolean e q u a l s ( Object obj ) { i f ( obj i n s t a n c e o f Person ) { r eturn compareto ( ( Person ) obj ) == 0 ; e l s e { r eturn f a l s e ; 6.6 Listor Definition 3 En lista är ordnad följd av element med följande egenskaper: Det finns en före-efter relation. Det finns ett positionsbegrepp (elementen behöver inte vara sorterade). Exempel på listor är den enkel-länkade och dubbel-länkade i figur 2 nedan. first next element next element next element null element first previous next element previous next element previous null element objekt objekt objekt objekt objekt objekt objekt (a) Enkel-länkad lista (b) Dubbel-länkad lista Figur 2 För att kunna traversera listan används en iterator. Här implementeras en enkel-länkad lista med en inre iteratorklass. Man får inte glömma metoden iterator i huvudklassen som skapar iterator objektet: p u b l i c c l a s s S i n g l e L i n k e d L i s t <E> implements I t e r a b l e <E>{ p r i v a t e ListNode<E> f i r s t ; p u b l i c I t e r a t o r <E> i t e r a t o r ( ) { r eturn new M y L i s t I t e r a t o r ( ) ; p u b l i c S t r i n g t o S t r i n g ( ) { S t r i n g B u i l d e r sb= new S t r i n g B u i l d e r ( ) ; sb. append ( [ ) ; ListNode<E> n=f i r s t ; while ( n!= n u l l ){ sb. append ( n. element. t o S t r i n g ( ) ) ; 14

15 i f ( n. next!= n u l l ){ sb. append ( ", " ) ; n=n. next ; sb. append ( ] ) ; r eturn sb. t o S t r i n g ( ) ; p u b l i c void addfirst (E x ) { ListNode<E> n = new ListNode<E>(x ) ; n. next = f i r s t ; f i r s t = n ; p u b l i c E removefirst { i f ( f i r s t==n u l l ){ throw new NoSuchElementException ( ) ; ListNode<E> temp = f i r s t ; f i r s t=f i r s t. next ; r eturn temp. element ; p u b l i c void addlast (E x ){ ListNode<E> n = new ListNode<E>(x ) ; i f ( f i r s t==n u l l ){ f i r s t = n ; e l s e { ListNode<E> p = f i r s t ; while ( p. next!= n u l l ){ p=p. next ; p. next= n ; p u b l i c E removelast ( ) { i f ( f i r s t==n u l l ){ throw new NoSuchElementException ( ) ; i f ( f i r s t. next == n u l l ){ ListNode<E> temp = f i r s t ; f i r s t = n u l l ; r eturn temp. element ; 15

16 ListNode<E> p = f i r s t ; ListNode<E> pre= n u l l ; while ( p. next!= n u l l ){ pre=p ; p = p. next ; pre. next=n u l l ; r eturn p. element ; p r i v a t e s t a t i c c l a s s ListNode<E> { p r i v a t e E element ; // data som l a g r a s p r i v a t e ListNode<E> next ; // r e f e r e r a r t i l l nästa nod... p r i v a t e c l a s s M y L i s t I t e r a t o r implements I t e r a t o r <E> { p r i v a t e ListNode<E> pos ; p r i v a t e m y L i s t I t e r a t o r ( ) { pos=f i r s t ; p u b l i c Boolean hasnext ( ) { r eturn pos!= n u l l ; p u b l i c E next ( ) { i f ( hasnext ( ) ) { ListNode<E> temp = pos ; pos=pos. next ; return temp. element ; e l s e { throw new NoSuchElementException ( ) ; Med javas API följer två färdiga listklasser: ArrayList<E> som implelenterats med en vektor och LinkedList<E> som implementerats med en dubbel-länkad cirkulär struktur. ArrayList används då man enbart gör insättningar i slutet av listan, då andra insättningar gör att element måste flyttas. Metoderna för get och set är däremot snabbare i arraylist. Interfacet för listor, List, anger att det även ska finnas särskilda operationer som returnerar en ListIterator: listiterator och listiterator(int i), där den sistnämnda börjar på index i. Interfacet ListIterator<E> ärver Iterator<E> och utvidgar med stöd för insättning av element och bakåttra- 16

17 versering. p u b l i c i n t e r f a c e L i s t I t e r a t o r <E> extends I t e r a t o r <E> { boolean hasprevious ( ) ; E p r e v i o u s ( ) ; void add (E x ) ;... Varning 2 ListIteratorn pekar inte på elementen i listan utan hela tiden mellan två element. Så previous och next returnerar objektet före och efter positionen i listan. Detta medför att det i en lista med n-element finns n+1 index (från 0 till n). 6.7 Stackar Definition 4 En stack är en följd av element där uttagning av element alltid sker på det element som satts in sist. The Last in is the first out (LIFO). Figur 3: Stack, LIFO. Det finns inget interface i javas API, det finns dock en klass Stack som ärver vector och ger stackfunktionalitet. Ett renodlat stack interface borde se ut ungefär så här: p u b l i c i n t e r f a c e Stack<E> { / Lägg x ö v e r s t på stacken. / void push (E x ) ; / Tag bort och r e t u r n e r a ö v e r s t a elementet. / E pop ( ) ; / Returnera ö v e r s t a elementet f r å n stacken. / E peek ( ) ; / Undersök om stacken är tom. / boolean isempty ( ) ; 6.8 Köer Definition 5 En kö är en följd av element där det element som lagts in först är det som kan tas ut eller tas bort. First in first out (FIFO). Ett interface för en kö i dess enklaste form skulle kunna vara: 17

18 OFFER POLL Figur 4: Kö, FIFO. p u b l i c i n t e r f a c e Queue<E> { / S ä t t e r in x s i s t i kön. / boolean o f f e r (E e ) ; / Tar reda på f ö r s t a elementet i kön. / E peek ( ) ; / Tar reda på och t a r bort f ö r s t a elementet i kön. / E p o l l ( ) ; / Undersöker om kön ä r tom. / boolean isempty ( ) ; Java.util har ett interface Queue som innehåller bland annat: För att lägga till: boolean add(e x), boolean offer(e x) För att ta bort: E remove(), E poll() För att ta reda på: E element(), E peek(); (den första metoden på varje rad genererar en exception, medans den andra returnerar ett specifikt värde). 6.9 Implementering av köer och stackar Det finns några olika alternativ när man väljer hur man vill implementera sina köer eller stackar: 18

19 Enklast är att använda en befintlig list-klass och enbart utnyttja de operationer som är specifika för en stack/ kö. Implementera en egen klass men delegera funktionaliteten till en list-klass. Implementera en egen klass med enkel datastruktur Stack genom att delegera till LinkedList p u b l i c c l a s s Stack<E> { p r i v a t e LinkedList <E> elements ; p u b l i c push (E x ) { elements. push ( ) ; p u b l i c E peek ( ) { r eturn elements. peek ( ) ; Egen klass för stack och kö En stack/kö kan implementeras med den enkla datastrukturer för enkel-länkad lista eller som en vektor. Fördelen med att implementera detta är att antalet metodanrop minskar jämfört om man skulle använda den delegerande metoden ovan. Enkel-länkad datastruktur för stack Stacken består av en referens till den första noden samt noder med next referens. Detta gör att alla operationer kan utföras på konstant tid, oberoende av stackens storlek. Enkel-länkad datastruktur för kö En kö implementeras som en enkel-länkad lista, med referenser till den första och sista noden samt noder med next referens. Också i kön kan alla operationer utföras på konstant tid oberoende av kölängd. Vektors datastruktur för stack En stack kan implementeras som en vektor med index för nästa lediga position. Detta ger en stack med konstant tid för operationerna, men bara så länge längden räcker till. Om man dubblar vektorlängden varje gång den överskrids kan operationerna fortfarande i medeltal gå att utföra på konstant tid. Vektors datastruktur för kö En kö kan implementeras som en vektor, om man använder index och låter vektorns struktur vara cirkulär så att första platsen är efterföljare till sista platsen. Vad som behövs utöver själva vektorn är index för första, respektive sista element, samt antalet element. Precis som i fallet med stacken måste storleken på kön ökas då den blivit full. 19

20 7 Algoritmers effektivitet, tidskomplexitet Definition 6 (Komplexitets begrepp) En algoritms komplexitet beskrivs ofta på tre nivåer: Effektivitet : Tidskomplexitet som funktion av problemets storlek. Minneskrav : Rumskomplexitet som funktion av problemets storlek. Svårighetsgrad : Ju mer komplicerad algoritm desto svårare att implementera och underhålla. Tidskomplexiteten är den mest intressanta analysen. En hög tidskomplexitet innebär att algoritmen är ineffektiv och dyr, medan en låg tidskomplexitet innebär en effektiv och billig algoritm Tiden för att lösa ett problem är ofta beroende av problemets storlek, men inte alltid. Om man ska summera 100 tal så går det generellt snabbare än att summera tal. Men att ta ut det i:te talet ur en vektor går att göra på konstant tid oavsett vektorns storlek. Med tidskomplexitet menar vi ett mätverktyg som ger oss möjlighet att jämföra olika algoritmers effektivitet, oavsett vilken plattform de körs på. Vi vill även kunna avgöra hur komplexiteten beror på problemets storlek, kvadratiskt, logaritmiskt, linjärt, etc. Vi introducerar därför tidskomplexiteten som T (n), där n är problemets storlek. Exempel 1 (Tidskomplexiteten för att summera n-st tal) Vid summeringen utförs n-st additioner och lika många tilldelningar. Detta ger att T (n) = n. Den reella tidsåtgången på en plattform blir då c T (n), där c är tidsåtgången för en addition på den specifika plattformen. 20

21 Exempel 2 (Summera vektor) Givet en vektor a=1,4,2,9,7 bilda en vektor med längd n, innehållande summan av de k första talen ur a, k 0, n 1. Det vill säga bilda sum(k) för k 0, n 1. Första talet i sum vektorn blir 0, ty 0 tal från a, andra talet blir 0+a(0)=1, tredje 0+a(0)+a(1)=5. osv. = sum=0,1,5,7,16 Två algoritmer för problemet ovan tas fram och jämförs: for ( int k = 0 ; k < n ; k++) { sum [ k ] = 0 ; for ( int i = 0 ; i < k ; i ++) { sum [ k ] = sum [ k ] + a [ i ] ; Listing 2: Algoritm 1 De operationer som utförs flest gånger finns i den innersta for-loopen, den inre for loopen körs beroende på k-värdet i den yttre for-loopen: k-värde för yttre for-loopen: antal ggr inre for-loopen körs: j j n-1 n-1 Den yttre for-loopen körs n gånger och för respektive körning körs den inre loopen 0, 1, 2..., n 1 ggr det vill säga den inre loopen körs n detta kan skrivas som n(n 1) 2, se Bevis 1. Tidskomplexiteten blir så T (n) n2 2 för stora n sum [ 0 ] = 0 ; for ( int k = 1 ; k < n ; k++) { sum [ k ] = sum [ k 1] + a [ k 1]; Listing 3: Algoritm 2 I algoritm 2 körs enbart en for-loop, då de tidigare värdena i summan utnyttjas räcker detta. forloopen utförs n 1 gånger och ger således algoritmen en tidskomplexitet på T (n) = n 1, där n är antalet element i vektorn sum. 21

22 7.1 Ordonotation Tidskomplexitets begreppet förenklas med införandet av ordonotation, i ordonotation stryks nämligen alla icke dominerande termer och om man så vill konstanter på dessa. Exempelvis: T (n) = 2n 2 + n = T (n) i ordonotation : O(2n 2 ) = O(n 2 ) (4) 7.2 Asymptotisk tidskomplexitet När man uppskattar tidskomplexiteten med ordonotation brukar man kalla denna uppskattning för algoritmens asymptotiska tidskomplexitet. 7.3 Olika tidskomplexiteter En algoritm med tidskomplexiteten T (n) = O(1) sägs ha konstant tidskomplexitet. Nedan, i figur 5, visas några olika benämningar på tidskomplexitets-karakteristik sorterade efter respektive karakteristiks växande. Figur 5: Olika tidskomplexiteter. Tidskomplexiteten kan även bero på indata, om man till exempel ska söka ett tal i en vektor, som matas in metoden, beror tidskomplexiteten på indatan Worst case och Average case Då tidskomplexiteten beror på indatan brukar man ange ett worst-case (W (n)) och ett averagecase (A(n)). Worst-case beräknas som W (n) = max(t i (n)) medan average beräknas A(n) = Pi T i (n), vilket gör average svårare eftersom P måste skattas. Exempel 3 W (n) för linjärsökning där n är vektorns längd. I värsta fall hittas inte det sökta objektet och for-loopen utförs från 0...n 1 det vill säga innehållet i for-loopen utförs n-gånger. Alltså är W (n) = n = O(n). A(n) för linjärsökning, med samma utgångsläge som ovan, fast med sannolikhet P att sökta värdet finns i vektorn. Sannolikheten att värdet finns på en viss position är P n, det vill säga alla positioner är lika troliga. A(n) blir så en summa som innehåller alla möjliga placeringar av värdet, samt även risken att värdet saknas: A(n) = p i T i (n) = p ( n) + (1 p) n (5) n 22

23 Speciellt för p = 1 fås A(n) = n+1 2 = O(n) 8 Rekursion Begreppet rekursion innebär kortfattat att man delar upp ett problem i mindre delproblem. En rekursiv funktion är typiskt en metod i koden som anropar sig själv. Många datastrukturer går att definiera rekursivt, t ex listor och träd. Figur 6: Kochs snöflinga konstrueras stegvis och som med många andra fraktaler, erhålls stegen från en rekursiv definition. Exempel 4 (Beräkna n! med hjälp av rekursion) En rekursiv implementering av problemet blir: p u b l i c s t a t i c i n t f a c t o r i a l ( i n t n ) { i f ( n == 0) { r e t u r n 1 ; e l s e { r e t u r n n f a c t o r i a l (n 1); 0! = 1, n! = n (n 1)! (6) När programmet hoppar till en ny metod sparas den aktuella raden, lokala variabler och parametervärden. På så vis kan programmet fortsätta där det slutade när undermetoden är färdig. Dessa data sparas som aktiveringsposter och placeras i en stack. Stacken byggs på och plockas ner allteftersom programmet går längre in i - och kommer tillbaka ut från rekursionen, se figur Rekursiv metod En rekursiv metod måste ha parametrar som anger problemets storlek. Ett eller flera basfall som löses direkt. Ett eller flera rekursiva anrop, som slutligen leder till ett basfall. I exemplet factorial ovan är n en parameter, n == 0 är basfallet och return n factorial(n 1) är det rekursiva anropet. 23

24 factorial(0) n=0 return 1 factorial(1) 1 n=1 return 1 * factorial(0) factorial(2) 1 n=2 return 2 * factorial(1) factorial(3) 2 n=3 return 3 * factorial(2) 6 Figur 7: Dataflöde då metoden factorial ovan utförs för n = 3. Figur 8: Stacken då metoden factorial ovan utförs för n =

25 Exempel 5 (Skriva ut tal baklänges) Problem: Givet ett heltal n 0. Skriv ut siffrorna i omvänd ordning. Basfall: Talet har bara en siffra. Rekursivt: Skriv först ut sista siffran, därefter övriga siffror i omvänd ordning. p u b l i c s t a t i c v o i d r e v e r s e ( i n t n ) { i f ( n < 0){ throw new I l l e g a l A r g u m e n t E x c e p t i o n (" Argument < 0 " ) ; e l s e i f ( n < 10) { System. out. p r i n t l n ( n ) ; e l s e { System. out. p r i n t l n ( n % 1 0 ) ; r e v e r s e ( n / 1 0 ) ; Alternativt gör man två metoder, en för att hantera anropet från användaren och en privat metod som utför rekursionen: p u b l i c s t a t i c v o i d p r i n t R e v e r s e ( i n t n ) { i f ( n < 0){ throw new I l l e g a l A r g u m e n t E x c e p t i o n (" Argument < 0 " ) ; e l s e { r e v e r s e ( n ) ; System. out. p r i n t l n ( ) ; p r i v a t e s t a t i c v o i d r e v e r s e ( i n t n ) { i f ( n < 10) { System. out. p r i n t l n ( n ) ; e l s e { System. out. p r i n t l n ( n % 1 0 ) ; r e v e r s e ( n / 1 0 ) ; 8.2 Rekursiv lista Hela list begreppet kan defineras som rekursivt. Basfall: Tom lista, n == 0. Rekursivt: Första element följt av lista med n 1 element. 25

26 Exempel 6 (Omvänt ordnad utskrift av lista) Man kan skriva ut innehållet ur en lista i omvänd ordning med hjälp av rekursion: public void p r i n t R e v e r s e ( ) { p r i n t R e v e r s e ( f i r s t ) ; private void p r i n t R e v e r s e ( ListNode<E> node ) { i f ( node!= null ) { p r i n t R e v e r s e ( node. n e x t ) ; System. out. p r i n t l n ( node. element ) ; Listing 4: Den rekursiva funktionen printreverse anropar sig själv med nästa element när den kommit ända in i rekursionen skriver den ut alla element utåt. basfallet med den tomma listan syns inte. Tidskomplexiteten för metoden är O(n). För att kunna utrycka metoderna rekursivt i en klass behöver vi tillgång till datastrukturen, detta har vi inte om vi använder javas färdiga list-klass. Har vi dock en egen list-klass som vi definierar som rekursiv så kan många metoder i den göras rekursiva. Exempel 7 (Hanois torn) n-st skivor ska flyttas från en pinne till en annan, till sin hjälp har man ett mellansteg. Reglerna är: Bara en skiva i taget får flyttas. En skiva som tas från en pinne måste genast läggas på en av de andra pinnarna. En större skiva får aldrig hamna ovanför en mindre (på samma pinne). Basfall: bara en skiva att flytta (n==1). Rekursivt: flytta de n 1 första skivorna till mellansteget. Flytta därefter den största skivan till destinationspinnen. Flytta slutligen de resterande skivorna från mellansteget till destinationspinnen. Se figur 9. p u b l i c v o i d move ( i n t n, i n t s t a r t, i n t dest, i n t temp ) { i f ( n == 1) { System. out. p r i n t l n (" Move from " + s t a r t + " t o " + d e s t ) ; e l s e { move ( n 1, s t a r t, temp, d e s t ) ; System. out. p r i n t l n (" Move from " + s t a r t + " t o " + d e s t ) ; move ( n 1, temp, dest, s t a r t ) ; 26

27 Figur 9: Rekursiv lösning av Hanoi-towers problement. Exempel 8 (Räkna färgrutor i rutnät) Antag ett tvådimensionellt rutnät. Problemet består i att finna antalet rutor i samma färg som är anslutna till rutan med kordinaterna x, y. Det vill säga hur många rutor ingår i det färgade objektet som innesluter x, y. p u b l i c i n t c o u n t C e l l s ( i n t x, i n t y ) { i f x, y u t a n f ö r r u t n ä t e t r e t u r n 0 ; e l s e i f rutan x, y är tom r e t u r n 0 ; e l s e töm rutan x, y r e t u r n e r a 1 + a n t a l r u t o r i de å t t a angränsande r u t o r n a s f l ä c k a r Exempel 9 (Binärsökning) För att söka ett värde i en sorterad vektor finns en effektiv rekursiv algoritm, binärsökning. Basfall 0 element, sökt element finns ej. Rekursivt: Jämför värdet med mittelementet i vektorn. Om värdet är mindre än mittelementet, fortsätt sökningen i den halvan av vektorn som har mindre värden än mittelementet. Om värdet är större, fortsätt sökningen i den större halvan. p u b l i c s t a t i c <E e x t e n d s Comparable<E>> i n t b i n a r y S e a r c h (E [ ] items, E t a r g e t ) { r e t u r n b i n a r y S e a r c h ( items, t a r g e t, 0, items. l e n g t h 1 ) ; p r i v a t e s t a t i c <E e x t e n d s Comparable<E>> i n t b i n a r y S e a r c h (E [ ] items, E t a r g e t, i n t f i r s t, i n t l a s t ) { i f ( f i r s t > l a s t ) { r e t u r n 1; e l s e { i n t mid = ( f i r s t + l a s t ) / 2 ; i n t compresult = t a r g e t. compareto ( items [ mid ] ) ; i f ( compresult == 0) { r e t u r n mid ; 27

28 e l s e i f ( compresult <0){ r e t u r n b i n a r y S e a r c h ( items, t a r g e t, f i r s t, mid 1 ) ; e l s e { r e t u r n b i n a r y S e a r c h ( items, t a r g e t, mid + 1, l a s t ) ; Linjärsökning är i värsta fall O(n). Binärsökningen är mycket effektivare: I värsta fall saknas det sökta värdet, annars börjar sökningen med en vektor av storlek n och går vidare: n/2,n/4,n/8,...1,0. Det krävs i värsta fall 2 log(n) halveringar, med konstant arbete. Algoritmen får därför tidskomplexitet: O(logn). 8.3 Samband mellan rekursion och induktion Matematisk induktion är en teknik för att finna matematiska mönster och ställa upp en bevisad formel för detta mönster. Bevisen görs i två steg: Visa att sambanden gäller för små värden på n. Visa att om man antar att sambandet håller för vilket heltal som helst n upp till ett visst värde k, så gäller det även för närmast större värde k + 1. Exempel 10 (En stege) Basfallet: Vi visar att vi når första trappsteget på stegen, n = 1. Induktionsantagande: Vi antar att vi kommit upp till steget n = a, där a är ett tal, vilket som helst. Induktionssteg:När vi står på steg a måste vi bevisa att vi kan nå nästa trappsteg, dvs steg n = a+1 Exempel 11 (aritmetisk talföljd) Summan av talen: 1, 2, 3,..., n kan skrivas som n(n+1) 2 Basfallet: Bevisa sambandet för n = 1. V L : S n = n och HL : S n = n(n+1) 2. Insättning av n = 1: Vänsterledet blir 1 och högerledet blir 1(1+1) 2 = 1 = V L = HL. Induktionsantagande: Antag att satsen stämmer för alla positiva heltal, a: S a = a = a(a+1) 2 Induktionssteget: Visa att satsen gäller även för nästa tal, a+1: S a+1 = a + (a + 1) = (a+1)((a+1)+1) 2 Visa att sedan att S a+1 är samma som S a + (a + 1). Skriver vi ut detta med talen får vi: a(a+1) 2 + (a + 1). Skriv om (a + 1) som 2(a+1) 2 för att få utseendet att likna det som för S a+1. Vi får så: a(a+1)+2(a+1) 2 minsta gemensamma nämnare till täljaren: (a + 1) ger: a(a+1)+2(a+1) 2 = (a+1)(a+2) 2 = (a+1)((a+1)+1) 2 28

29 8.4 Induktion för att verifiera rekursion p u b l i c s t a t i c i n t f a c t o r i a l ( i n t n ) { i f ( n == 0) { r eturn 1 ; e l s e { r eturn n f a c t o r i a l (n 1); När n = 0 blir resultatet 1 vilket är korrekt med avseende på definitionen av n!. Antag att algoritmen ger korrekt resultat för 0 n k. Anrop av factorial(k + 1) ger (k + 1) factorial(k + 1 1) = (k + 1) factorial(k). Enligt antagandet ovan ger f actorial(k) korrekt resultat för k!. Vi får därför resultatet (k + 1) k! = (k + 1)!, V. S. B. 8.5 Divide and conquer approach Avser här tekniken att dela upp problem i rekursiva algoritmer som gör två rekursiva anrop i varje iteration. Se exempel i figure Figur 10: Sortering av vektor med divide-conquer approach. Definition 7 Fibonacci-talen definieras som följden: F n = F n 1 + F n+2 för n 2 F 0 = 0, F 1 = 1. Exempel 12 (Fibonacci - divide and conquer) Den enklaste implementationen av Fibonacci, se koden nedan, är ineffektiv då samma tal beräknas gång på gång (O(2 n )). En divide and conquer approach med dynamiskprogrammering kan få ner problemet till O(n). 29

30 p u b l i c s t a t i c l o n g f i b ( i n t n ) { i f ( n <= 1) { r e t u r n n ; e l s e { r e t u r n f i b ( n 1) + f i b ( n 2 ) ; Koden ovan löser problemet enligt figur 11. Ett effektivare sätt att lösa problemet är om man Figur 11: Fibonacci generering, komplexitet O(2 n ). sparar alla tidigare uträkningar i en tabell och återanvänder dem: p u b l i c l o n g f i b ( i n t n ) { l o n g [ ] t a b l e = new l o n g [ n +1]; // skapa en t a b e l l f o r ( i n t i = 0 ; i <= n ; i ++) { t a b l e [ i ] = 1; // n e g a t i v t värde <=> e j b e r ä k n a t r e t u r n r e c f i b ( t a b l e, n ) ; p r i v a t e l o n g r e c f i b ( l o n g [ ] t a b l e, i n t n ) { i f ( t a b l e [ n ] < 0 ) { i f ( n<=1){ t a b l e [ n]=n ; e l s e { t a b l e [ n ] = r e c f i b ( t a b l e, n 1) + r e c f i b ( t a b l e, n 2); r e t u r n t a b l e [ n ] ; Nu blir istället anropen färre, då vardera beräkning bara utförs en gång. Se figur

31 Figur 12: Fibonacci generering, komplexitet O(n). Nedan presenteras en alternativ lösning med iterativ approach. Också den O(n). p u b l i c l o n g f i b ( i n t n ) { i f ( n <= 1) { r e t u r n n ; e l s e { i n t nbr1 = 0 ; i n t nbr2 = 1 ; i n t r e s = 0 ; f o r ( i n t i = 2 ; i <= n ; i ++) { r e s = nbr1 + nbr2 ; nbr1 = nbr2 ; nbr2 = r e s ; r e t u r n r e s ; 8.6 Val av lösning När man väljer lösningsmetod för ett visst problem bör man tänka på följande: Rekursion bör användas då det är svårt att uttrycka lösningen icke rekursivt. Rekursion bör användas om den ger en effektivare lösning. Rekursion är lika effektiv som en annan lösning men enklare att förstå och implementera. Fördelar med rekursion är: Det är lätt att översätta den rekursiv algoritm till kod. Det är enkelt att verifiera en rekursiv algoritm. 31

32 9 Grafiska användargränssnitt Grafiska användargränssnitt examineras inte i samband med tentamen utan enbart på laboration 3 och 6. De som väljer att lösa sudoku eller implementera en kalkylator som inlämningsuppgift får ytterligare träning på detta. 10 Träd Definition 8 Ett träd är en icke-linjär struktur som bygger på att en parent-nod har flera chlidnoder. Se strukturen nedan i figur 13. Figur 13: Trädstrukturen. En träd struktur kan definieras rekursivt: som ett tomt träd om noder saknas, som en rot med noll eller flera subträd Terminologi En nod som är över en annan är dess ancestor, den underliggande noden är descendant. Är noderna direkt anslutna så är den övre parent och den undre child. Den översta noden i trädet saknar parents och kallas rot. Noder som saknar childs kallas leafs. Noderna är anslutna till varandra med branches. Trädets nivåer räknas från roten och uppåt. Roten är på nivå 1 och ett child är på nivå parent level + 1. Ett tomt träd har höjd 0. Höjden är densamma som den maximala nivån i trädet: height = max level Binära träd Definition 9 Ett träd är binärt om varje nod har högst två barn eller högst två subträd. Ett träd är strikt binärt om varje nod har noll eller två barn. Terminologin utvidgas här med höger-, vänster subträd och höger-, vänster barn Aritmetiska uttryck, utryck med +,-,* och / kan illustreras med strikt binära träd. Jämför med dataflow graphs i digital signal behandling. Då lagras operander i löv (lövens värden) och operatorer i de andra noderna. Ett träds värde är värdet av subträden applicerade på operatorn i roten. Nedan visas hur en implementering av ett binärt träd kan se ut: 32

33 p u b l i c c l a s s BinaryTree<E> { p r i v a t e Node<E> root ; p u b l i c BinaryTree ( ) { root=n u l l ;... t r ä d o p e r a t i o n e r... p r i v a t e s t a t i c c l a s s Node<E> { p r i v a t e E data ; p r i v a t e Node<E> l e f t ; p r i v a t e Node<E> r i g h t ; p r i v a t e Node (E data ) { t h i s. data=data ; l e f t=r i g h t=n u l l ;... Figur 14: Implementeringen av en nod visualiserad Traversering Traversering innebär evaluering av alla noder i trädet. Många olika operationer på trädet kan ses som traverseringar. Man kan traversera trädet på olika sätt, nedan följer tre rekursiva metoder för traversering: Preorder - först roten, sedan vänster subträd i preorder, därefter höger subträd i preorder. Inorder - först vänster subträd i inorder, sedan roten och därefter höger subträd i inorder. Postorder - först vänster subträd i postorder, sedan höger subträd i postorder och därefter roten. Enligt resonemangen ovan bestäms alltså ordern av när man evaluerar roten. Sub träden behandlas hela tiden rekursivt, hela vägen ner till roten. 33

34 11 Binära sökträd I ett binärt sökträd lagras element i växande ordning, från vänster- till höger subträd. Det vill säga elementen i vänster subträd är hela tiden mindre än roten, som i sin tur är mindre än höger subträd. Strukturen är skapad för att man lätt ska kunna hitta, sätta in och ta bort element. (Dubbletter är inte tillåtna). Ordningen som bygger upp ett binärt sökträd medför att en inorder-traversering returnerar elementen i växande ordning Sökning i binära sökträd För att effektiv söka ett element i ett binärt sökträd kan man utnyttja strukturen enligt följande algoritm: Är elementet i roten, om ja så är sökningen klar. Om elementet vi söker är mindre än roten gå till vänster child och jämför. Annars gå till höger child. Upprepa tills sökt element är funnet eller nästa nod att jämföra med är null (misslyckad sökning). Algoritmen innebär i praktiken att man i en sökning följer en gren tills man hittar elementet man söker eller grenen tar slut Implementering av binärt sökträd En implementering av ett generiskt binärt sökträd kan se ut: p u b l i c c l a s s BinarySearchTree<E extends Comparable<? super E>> { p r i v a t e Node<E> root ; p u b l i c BinarySearchTree ( ) { root=n u l l ; p u b l i c boolean add (E item ) {... p u b l i c E f i n d (E t a r g e t ) {... p u b l i c boolean c o n t a i n s ( Object t a r g e t ) {... p u b l i c boolean remove (E t a r g e t ) { n ä s t l a d k l a s s Node<E> som r e p r e s e n t e r a r nod... Find funktionen kan skrivas: p u b l i c E f i n d (E t a r g e t ) { r eturn f i n d ( root, t a r g e t ) ; p r i v a t e E f i n d ( Node<E> n, E t a r g e t ) { i f ( n == n u l l ) { 34

35 r eturn n u l l ; i n t compresult = t a r g e t. compareto ( n. data ) ; i f ( compresult == 0) { r eturn n. data ; Insättning: Vid insättning av nya element ska ordningen i trädet bevaras och dubletter får inte förekomma. Insättning kan utföras med hjälp av misslyckad sökning. Om sökningen misslyckas finns inte elementet i trädet och ska sättas in på det sist evaluerade stället i trädet, där misslyckandet konstaterats, se figur 18. Figur 15: Insättning i binärt sökträd. p u b l i c boolean add (E item ) { i f ( root == n u l l ) { root= new Node<E>(item ) ; r eturn true ; e l s e { r eturn add ( root, item ) ; p r i v a t e boolean add ( Node<E> n, E item ){ i n t compresult = item. compareto ( n. data ) ; i f ( compresult == 0){ r eturn f a l s e ; 35

36 i f ( compresult <0){ i f ( n. l e f t==n u l l ){ n. l e f t= new Node<E>(item ) ; r eturn true ; e l s e { r eturn add ( n. l e f t, item ) ; e l s e { i f ( n. r i g h t == n u l l ){ n. r i g h t = new Node <E>(item ) ; r eturn true ; e l s e { r eturn add ( n. r i g h t, item ) ; Borttagning: För att kunna ta bort ett element ur trädet måste man först söka upp det. Därefter kopplar man föräldern till något av barnen. Sammankopplingen sker på olika sätt beroende på hur många barn noden som ska tas bort har. Enklaste fallen är när noden har noll eller ett barn. Fallet med två barn är svårare. Figur 16: Borttagning av nod med noll barn Tidskomplexitet hos binära sökträd, en funktion av höjden De vanliga operationerna på binära sökträd innebär praktiskt att man söker utmed en gren i trädet. För att kunna analysera tidskomplexiteten för ett specifikt träd måste man då ha ett samband 36

37 Figur 17: Borttagning av nod med ett barn. Figur 18: Borttagning av nod med två barn. mellan trädets höjd och antal noder. Höjd begränsningen uppåt är lätt att göra, då höjden omöjligt kan överstiga antal noder. h n (7) Neråt begränsas höjden enligt: nivå 1 har högst en nod, nivå 2 högst 2, nivå 3 högst 4. Det vill säga sambandet på varje nivå är 2 i 1, där i är nivån. Den högsta nivån i ett träd av höjd h är per definition h. Alltså n i h 1 = 2 h 1. (En analogi kan här göras med de binära talsystemet: ett binärt ord med 8-bitar med fyllt med 1:or har ju värdet = 255). För att få höjden som funktion av antalet noder löser vi ut h och får så: h 2 log(n + 1) (8) 37

38 11.4 Garanterat minimal höjd Två olika strukturer av binära träd garanterar minimal höjd. Perfekt binärt träd kallas ett binärt träd som är fullt på alla nivåer och vars alla löv befinner sig på samma nivå. Definitionen innebär att höjden alltid är h = 2 log(n + 1). Figur 19: Ett perfekt binärt träd. Komplett binärt träd kallas ett binärt träd som har alla nivåer fulla utom den högsta, vars noder är samlade i på vänster sida. Höjden fås här från intervallet (2 h 1 1) < n (2 h 1) Löser vi ut h: 2 h 1 < n h = 2 log(n + 1) h < log(n + 1). Vilket ger h 2 log(n + 1). Figur 20: Ett komplett binärt träd. Ett träd med minimal höjd har alltså i värsta fall tidskomplexiteteno( 2 log(n)) Problematik: insättningsordning Insättnings ordningen påverkar trädet höjd. Om man sätter in 1,2,3...,n får man en rak pinne som inte alls är ideal. Sätter man in 4,2,1,6,5,3,7 får man en finare struktur. Det ideala trädet ha noderna så nära roten som möjligt. Detta innebär att höjden blir O( 2 log(n)). Definition 10 (Idealisk form) Ett binärt sökträd har idealisk form om: Alla nivåer utom den högsta har har maximalt antal noder. Det finns ingen bra algoritm som garanterar denna idealiska form. Däremot räcker det att trädets höjd är proportionerlig mot 2 log(n). Detta finns det effektiva insättning och borttagnings algoritmer för. Definition 11 (Balanserat binärt sökträd, AVL-träd) Ett binärt träd är balanserat om det för varje nod i trädet gäller att höjdskillnaden mellan dess båda subträd är högst ett. Adelson-Velsky och Landis (AVL) som står bakom definitionen av det balanserade binära sökträdet bevisade också att detta ha en höjd begränsad av: h log(n) Algoritmer för att hålla binära sökträd balanserade (AVL-träd) Algoritmerna som arbetar för att balansera upp binära sökträd gör detta med hjälp av rotation, se figur

39 Figur 21: Rotationer på AVL-träd Detektera obalans För att hålla reda på balansen i trädet kan man införa ett balance-attribut i nodklassen. I detta attribut bokför man sedan höjdskillnaden mellan höger och vänster subträd. När höjden av ett subträd ändras, tex vid insättning eller borttagning, uppdaterar man attributen. Om höjdskillnaden är > 1 eller < 1 så måste detta åtgärdas med rotationer. Efter rotationerna blir absolutbeloppet av höjden 1 och trädet är balanserat Kostnad för att balansera ett träd Kostnaden för att balansera ett tidigare balanserat träd efter en insättning är maximalt en enkeleller dubbelrotation. Om obalans uppstår efter en borttagning ur ett tidigare balanserat träd så kan det behövas en enkel- eller dubbelrotation i varje nod på vägen från den nod där obalansen uppstod till roten för att återställa balansen. 39

40 Höjden i det balanserade trädet förblir O( 2 log(n)) om man efter varje förändring balanserar det igen. Varje rotation i trädet kostar enbart O(1), så detta är vettigt att göra. Däremot kräver varje balansering att alla balance-attribut från den insatta noden upp till roten uppdateras. Detta ger en värsta-falls-kostnad på O( 2 log(n)). 12 Set Definition 12 (Set) Ett set är en mängd element utan dubbletter. Interfacen Set och Collection har samma operationer. Men i Set tillåts inte dubbletter Sorted Set SortedSet förutsätter att elementen i setet är jämförbara, det vill säga implementerar någon form av comparator-objekt. SortedSets iterator går igenom mängden i växande ordning. Dessutom innehåller SortedSet några metoder som är specifika för sorterade mängder: returnera minsta element, returnera största element Set klasser Två klasser som implementerar Set är: TreeSet som implementerar SortedSet i form av Red-Black-tree som också den har en garanterad höjd på O( 2 log(n)). HashSet som använder en hashtabell TreeSet TreeSet har klassrubriken och flera konstruktorer: p u b l i c c l a s s TreeSet<E> extends AbstractSet <E> implements SortedSet <E>{ p u b l i c TreeSet ( ) {... p u b l i c TreeSet ( Comparator<? super E> c ) { E förutsätts alltså inte implementera Comparable istället ges den som användaren möjlighet att välja om man vill lagra en klass som implementerar Comparable (den första konstruktorn ovan) eller en klass med egen Comparator som parameter (den andra konstruktorn ovan) Interfacet Comparator Själva vitsen med interfacet Comparator är att ge användaren möjlighet att jämföra objekt på olika sätt. Tillexempel för att sortera personer både beroende på personnummer och beroende på namn. För att sortera ett treeset beroende på namn skickas en Comparator med till sorterings metoden, se exempel 13 nedan. (Implementeringar av interfacet Comparable implementerar en metod compareto). 40

41 p u b l i c i n t e r f a c e Comparator<T> { / Compares i t s two arguments f o r order. Returns a n e g a t i v e i n t e g e r, zero, or a p o s i t i v e i n t e g e r as the f i r s t argument i s l e s s than, equal to, or g r e a t e r than the second. / i n t compare (T e1, T e2 ) ; Exempel 13 (Interfacet Comparator) Nedan visas ett exempel med Person klassen som tack vare två Comparator-klasser kan sorteras på olika sätt. p u b l i c c l a s s Person { p r i v a t e S t r i n g name ; p r i v a t e S t r i n g pnbr ;... p u b l i c c l a s s NameComparator implements Comparator<Person> { p u b l i c i n t compare ( Person p1, Person p2 ) { r e t u r n p1. getname ( ). compareto ( p2. getname ( ) ) ; p u b l i c c l a s s NbrComparator implements Comparator<Person> { p u b l i c i n t compare ( Person p1, Person p2 ) { r e t u r n p1. getnbr ( ). compareto ( p2. getnbr ( ) ) ;... / Detta t r ä d kommer a t t ordnas e f t e r namn / TreeSet <Person> nametree = new TreeSet <Person >(new NameComparator ( ) ) ; / Detta t r ä d kommer a t t ordnas e f t e r personnummer / TreeSet <Person> nbrtree = new TreeSet <Person >(new NbrComparator ( ) ) ; Person p1 = new Person (... ) ; Person p2 = new Person (... ) ; nametree. add ( p1 ) ; nametree. add ( p2 ) ; nbrtree. add ( p1 ) ; nbrtree. add ( p2 ) ; 41

42 13 Map I interfacet map betraktas alla element som två delade, bestående av en unik nyckel och ett värde. Den vanliga användingen av en map är att nyckeln används för att söka upp värdet, jämför med en telefonkatalog eller databas Map klasser Två klasser som implementerar Map är: TreeMap som använder sökträd och innehåller operationerna: keyset() som garanterar att den returnerade mängden är ordnad. keyset().iterator() returnerar en iterator som går igenom elementen i växande ordning. HashMap som använder en hashtabell Några metoder i Map p u b l i c i n t e r f a c e Map<K,V> { V get ( Object key ) ; boolean isempty ( ) ; V put (K key, V value ) ; V remove ( Object key ) ; i n t s i z e ( ) ; Set<K> keyset ( ) ; C o l l e c t i o n <V> v a l u e s ( ) ; Set<Map. Entry<K,V>> entryset ( ) ; // Returnerar en mängd Entry objekt. / Representerar e t t nyckel värdepar / p u b l i c i n t e r f a c e Entry<K,V> { K getkey ( ) ; V getvalue ( ) ; V setvalue (V) ; // ändrar värdet t i l l V och // r e t u r n e r a r det gamla värdet 13.3 Implementera Map med sökträd För att kunna lagra nyckel-värdeparen i ett träd görs en inre klass som representerar ett par. Denna typ används sedan för att lagra värdena i ett binärt sökträd. p r i v a t e s t a t i c c l a s s Entry<K extends Comparable<K>, V> implements Comparable<Entry<K, V>>, Map. Entry<K, V> { p r i v a t e K key ; p r i v a t e V value ; 42

43 p r i v a t e Entry (K key, V value ){ t h i s. key=key ; t h i s. value=value ; p u b l i c K getkey ( ) { r eturn key ; p u b l i c V getvalue ( ) { r eturn value ; p u b l i c V setvalue (V val ){ V temp=value ; value=val ; r eturn temp ; p u b l i c i n t compareto ( Entry<K, V> rhs ){ r eturn key. compareto ( rhs ) ; Klassen mytreemap nedan används för att implementera trädet: p u b l i c c l a s s MyTreeMap<K extends Comparable<K>,V> implements Map<K, V> { p r i v a t e BinarySearchTree<Entry<K, V>> thetree = new BinarySearchTree <Entry<K, V> >(); p u b l i c V get ( Object key ) { Entry<K, V> found= thetree. f i n d ( new Entry<K, V> ( (K) key, n u l l ) ) ; i f ( found!= n u l l ){ r eturn found. getvalue ( ) ; e l s e { r eturn n u l l ; p u b l i c V put (K key, V value ) { Entry<K,V> found= thetree. f i n d (new Entry<K, V>(key, n u l l ) ) ; i f ( found!= n u l l ){ r eturn found. setvalue ( value ) ; e l s e { thetree. add (new Entry<K, V> ( key, value ) ) ; r eturn n u l l ; 43

44 14 Hashtabeller I ett specialfall med Map och Set, där nycklarna är tal på ett intervall 1..n, kan en vektor användas: Elementet med nyckel k placeras på plats k i vektorn. Sökning, borttagning och insättning blir då detsamma som direkt access till plats k, operationerna får då tidskomplexitet O(1). En generalisering kan göras om man översätter alla nycklar till heltal i ett visst intervall kan man alltid använda en vektor, så länge talen inte kommer att överlappa varandra. Definition 13 (Hashfunktion) En funktion som översätter en nyckel till ett heltal. Per definition översätter hashfunktionen en stor mängd nycklar till en liten mängd heltal, detta medför att kollisioner kommer uppstå. Hashfunktionens kvalitet mäts genom antalet kollisioner den ger upphov till. Den översatta nyckeln kallas hashkod och kan användas som index på en vektor Sluten hashtabell I en sluten hashtabell används helt enkelt en vektor för lagring av elementen. Kollsioner hanteras med hjälp av: Linjär kollisionshanteringsteknik innebär att man sätter in det kolliderande elementet på första lediga plats efter den där det skulle hamnat om ingen kollision inträffat. Tabellen betraktas som cirkulär, så 0 kommer efter tablesize 1. Då det ofta förekommer att samma hashkod upprepas kommer kluster bildas i tabellen. Detta är ett problem då stora kluster gör sökning i tabellen långsam. Borttagning ur tabellen leder också det till problematik då en tom plats indikerar att inget värde med den nyckeln sats in. För att kompensera vid borttagning sätts en markör, som indikerar att platsen är inaktiv, på den tömda platsen. Värsta fallet för sökning,insättning och borttagning är om alla element hamnat i en följd i tabellen, detta är i och för sig osannolikt, men om det händer måste man evaluera alla platserna i en följd. Detta ger operationerna en värsta tidskomplexitet på O(n). Vid halvfull tabell får man i medeltal komplexitet O(1). Kvadratisk kollisionshanteringsteknik är en bättre teknik att hantera kollisioner på då den är konstruerad för att motverka klustring. Detta görs genom att algoritmen vid en kollision först prövar nästa plats, därefter platsen 4steg framåt, därefter 9 steg framåt enligt: hv al, hv al + 1, hv al + 2 2, hv al + 3 2,..., hv al + i2,... (hv al = hashv alue) (9) Den kvadratiska kollisionshateringen introducerar dock ny problematik. Till exempel är det inte säkert att man alls hittar en ledig plats, trotts att det finns, se exempel 14. Värsta tidskomplexiteten är precis som vid linjär kollisionshantering: O(n), fast i praktiken får man mindre klustring. Exempel 14 Antag att hash-tabellens storlek är 16 och man använder hashfunktionen x%16: Insättning av element med nycklarna 0, 16, 32, 64 = samtliga hashas till plats 0. 44

45 14.2 Öppen hashtabell (separate chaining) En öppen hashtabell använder sig av listor för att hantera kollisioner. Varje vektor element innehåller en lista, som i sin tur innehåller alla element som hashats till den listans vektor position. Det vill säga lista nummer k innehåller alla element med hashkod k. Fördelen med en öppen hashtabell är att problematiken som uppstod i den slutna tabellen vid borttagning, det vill säga tomma luckor mitt i tabellen, inte längre är ett problem. I java implementeras öppna hashtabeller i HashSet och HashMap. Värsta fallet vid sökning uppstår då alla element hamnat i samma lista, -något som i och för sig är osannolikt om man har en bra hashfunktion, innebär en värsta tidskomplexitet på O(n). En bra hashfunktion ger alla positioner i tabellen lika stor sannolikhet. Detta i samband med en hashtabell som inte är fylld till mer än 2 tabelsize ger en medelkomplexitet på O(1) Metoden hashcode() I Object-klassen finns en metod hashcode() som översätter ett objekt till ett heltal. Implementeringen är gjord så att olika objekt om möjligt avbildas på olika heltal. Ofta måste man skugga denna metod (och equals()) i den klass vars objekt ska fungera som nyckel i hashtabellen (detta är t ex gjort i String, Integer, mfl.). Objekt för vilka equals ger true bör också få samma hashkod. Exempel 15 (hashcode() för sträng) Skuggningen av hashcode() som görs i String returnerar för en sträng s 0, s 1, s 2,..., s n 1 : ascii(s 0 ) 31 n 1 + ascii(s 1 ) 31 n 2 + ascii(s 2 ) 31 n ascii(s n 1 ) (10) Eftersom 31 är ett primtal får man relativt få kollisioner Sökning i öppen hashtabell Internt i hashset och hashmap används hashcode() och equals(object) för att finna element: Med x.hashcode()%tablesize beräknas först platsen för elementet med nyckel x. Därefter genomsöks listan på platsen efter x med hjälp av equals metoden Använda HashMap Här, nedan, är nycklarna av typen String och därför är hashcode() redan omdefinierad. HashMap<String, Person> map = new HashMap<String, Person >(); Person p = new Person (" Kaj... Person q = map. get (" Kajsa " ) ; i f ( q!= n u l l ) {... 45

46 14.5 Använda HashSet I exempelkoden nedanför används inte nycklar av typen String. HashSet översätter istället hela objektet till med hashcode. Därför krävs en skuggning av equals() och hashcode() i Person. HashSet<Person> s e t = new HashSet<Person >(); Person p = new Person (" Kajsa " ) ; s e t. add ( p ) ;... i f ( s e t. c o n t a i n s ( new Person (" Kajsa " ) ) ) { System. out. p r i n t l n (" Kajsa found " ) ; e l s e { System. out. p r i n t l n t (" Kajsa not found " ) ; Skuggas inte hashcode i Person hittas troligen inte objektet. När Kajsa sätts in beräknas hashkoden för objektet som p refererar till. När vi söker efter Kajsa baseras sökningen på hashkoden av det objekt som är parameter till contains-metoden. Detta är ett annat objekt, om än med samma namn. Sökningen utgår från den senares hashkod och dennas respektive plats i vektorn, eftersom hashkoden konstruerats för ett helt annat objekt är det högst osannolikt att dennes plats sammanfaller med objektet som lagts in tidigare. I koden nedan visas en Person-klass med equals och hashcode överskuggade på så vis att problematiken ovan undviks: c l a s s Person { p r i v a t e S t r i n g name ; // namn... // ö v r i g a a t t r i b u t // konstruktor och ö v r i g a metoder p u b l i c boolean e q u a l s ( Object rhs ) { i f ( rhs i n s t a n c e o f Person ) { r eturn name. e q u a l s ( ( ( Person ) rhs ). name ) ; e l s e { r eturn f a l s e ; p u b l i c i n t hashcode ( ) { r eturn name. hashcode ( ) ; 15 Prioritetsköer En prioritetskö skiljer sig från en vanlig kö genom att prioritera det viktigaste först istället för att prioritera det äldsta först. 46

47 Exempel 16 Patienter som väntar i en akutmottagning kan ses som en form av prioritetskö. Allvarligast skadad/sjuk går först. Elementen i prioritetskön innehåller ett eller flera attribut som bestämmer dess, elementens, prioritet. Flera element kan ha samma prioritet. En prioritetskö ska ha metoder för: insättning samt hämtning/borttagning av högst prioriterade elementet PriorityQueue I java finns det inget speciellt interface för prioritetsköer, man använder istället interfacet för Queue. Klassen priorityqueue implementerar Queue. p u b l i c c l a s s PriorityQueue<E> implements Queue<E> { // Konstruktor f ö r o bjekt som implementerar Comparable. PriorityQueue ( ) {.. // Jämför elementen med h j ä l p av komparatorn c. PriorityQueue ( i n t i n i t i a l C a p a c i t y, Comparator<? super E> c ) {... //Lägg t i l l e t t element i kön. boolean o f f e r (E x ) {... // Returnerar värdet med minst p r i o r i t e t s a t t r i b u t. E peek ( ) {... //Tar bort och r e t u r n e r a r värdet med minst p r i o r i t e t s a t t r i b u t. E p o l l ( ) { Implementering av prioritetskö - tidskomplexiteter Om prioritets kön implementeras som en lista eller en heap fås lite olika tidskomplexiteter. Sorterad lista peek, poll blir O(1). Offer blir O(n) eftersom elementets plats måste sökas. Osorterad lista peek, poll blir O(n) medan offer blir O(1) eftersom elementet kan sättas in först. Heap Ger effektivare operationer, se definition Heapar Definition 14 En heap är ett komplett binärt träd (obs: inte ett sökträd) där varje nod innehåller ett element som är barnens element. Detta innebär att trädets rot alltid innehåller minsta elementet. 47

48 16.1 Heap i vektor En heap kan lagras i en vektor, med roten på plats 0. Barnen till nod i placeras på platsen 2i+1 och 2i+2. Omvänt finns föräldern till nod j på platsen j 1 2. En vektor implementering kan se ut som här nedanför: p u b l i c c l a s s PriorityQueue<E> implements Queue<E> { p r i v a t e E [ ] queue ; p r i v a t e i n t s i z e ;... k o n s t r u k t o r e r... boolean o f f e r (E x ) {... E peek ( ) {... E p o l l ( ) { Insättning Offer implementeras så insättning sker på första lediga plats i vektorn. Därefter utförs byten uppåt i vektorn till rätt ordning uppåt (kallat percolate up eller add leaf). Exempel 17 (Insättning i heap-vektor) Insättning av ett element med nyckeln 1 i heapen i figur 22 nedan: Figur 22: Heapen före insättning. Bytena som sker vid insättning illustreras i figur 23: Figur 23: Insättnings metodik. Den insatta 1:an bubblar stegvis upp i trädet (percolate up). 48

49 Tidskomplexitet för insättning Eftersom Heapen är ett komplett binärt träd så är höjden begränsad till h log(n), för n-st noder. Vid insättning behöver den nya noden i värsta fall jämföras och bytas med alla element på väg upp till roten. Dessa är h-st så jämförelserna blir i värsta fall O(log(n)). I medelfall blir det dock bara O(1) byten Peek Minsta elementet finns alltid på platsen 0 i vektorn så peek är alltid O(1) Poll P oll implementeras på linknande sätt som insättning, tag bort noden på plats 0. Den tomma positionen, 0, i vektorn fylls sedan med det sista elementet, därefter byts elementet i 0 positionen med det minsta av sina barn, om de är mindre. elementet bubblar ner i trädet tills det minsta elementet hamnat i roten. Exempel 18 (Poll i heap-vektor) Utför poll på vektorn i figur 24: Figur 24: Heapen före poll. Bytena som sker illustreras i figur 25 här nedanför. Figur 25: Det sista elementet läggs först och bubblar ner i trädet, omvänt mot vid insättning Tidskomplexitet för poll I värsta fall måste byten och jämförelse ske hela vägen från roten ut i ett av löven. Detta leder till en värsta tidskomplexitet på O(log(n)). Eftersom det är en nod långt nedifrån som sätts in i 0-positionen måste byten sannolikt ske hela vägen ner till ett löv, så medelfallet visar sig också vara O(log(n)). 49

50 16.2 Heap av osorterad samling I det fallet man vill bygga en heap av en osorterad samling, kan man sätta in alla element från den osorterade samlingen i en från början tom kö med hjälp av en for-each eller while-loop. Detta motsvarar O(n log(n)), men kan effektiviseras om man har direkt tillgång till heapens vektor. För en prioritetskö som implementeras med en heap kan konstruktorn se ut: PriorityQueue ( C o l l e c t i o n <? extends E> c ) { q =... ; // skapa en vektor, med t i l l r ä c k l i g s t o r l e k / Lägg över a l l a element ur c i vektorn q / I t e r a t o r <? extends E> i t r = c. i t e r a t o r ( ) ; i n t i = 0 ; while ( i t r. hasnext ( ) ) { q [ i ] = i t r. next ( ) ; i ++; s i z e =c. s i z e ( ) ; h e a p i f y ( ) ; / / Heapify är en hjälpmetod Hjälpmetoden Heapify Heapify ska bygga själva heapen av vektorn, nerifrån och upp (percolate down) med början på noden som finns på plats n/2 1 därefter noden på plats n/2 2,..., 0, se figurer nedan. Figur 26: Börja med det inringade subträdet. 130 finns på plats n/2 1 i vektorn. Figur 27: Fortsätt med plats n/2 2 i vektorn. Där finns elementet

51 Figur 28: Därefter behandlas roten, som i detta fall byts med vänster barn, därefter fortsätter percolate-down i subträdet (som i fallet med poll) Heapifys tidskomplexitet Metoden heapify börjar på den näst nedersta nivån och utför här maximalt ett byte i varje underträd, då underträden har maxhöjd 1. I nästa steg är algoritmen på nivån ett steg högre upp, här är noderna visserligen färre men höjden på subträden är här max 2, därför blir det max 2 byten. Utfallet antal noder och höjd upprepas när man itererar uppåt i trädet. Man kan visa att heapify kostar O(n), där n är antalet element i vektorn. Detta kan jämföras med om man byggde trädet succesivt genom användning av metoden offer där de sista elementet hela tiden uppdateras och byts med noder uppåt i vektorn tills trädet är en heap. Detta är mer tidskrävande då. för visso tidiga insättningar kan lätt bytas upp till roten, men ju längre man kommer desto längre blir grenarna som fungerar som byteskedjor för noderna Heapify implementering Med en färdig metod för percolatedown blir implementeringen trivial: p r i v a t e void h e a p i f y ( ) { f o r ( i n t i = ( s i z e 2) / 2 ; i >= 0 ; i ) { percolatedown ( i ) ; Sista elementet finns på plats size 1 i vektorn och dess förälder finns på plats (size 2)/2. percolatedown fungerar som så att den börjar med noden på plats i och utför byten nedåt i heapen så länge ordningen är felaktig (metoden används även av operationen poll) Sortering med prioritetskö Exempel 19 (Effektiv sortering med hjälp av prioritetskö) Antag att man effektivt vill sortera en vektor a. PriorityQueue <E> myq = new PriorityQueue <E>(); f o r ( i n t i = 0 ; i < a. l e n g t h ; i ++) { myq. o f f e r ( a [ i ] ) ; f o r ( i n t i = 0 ; i < a. l e n g t h ; i ++){ a [ i ]=myq. p o l l ( ) ; 51

52 Koden ovan ger en tidskomplexitet beroende av n = a.length. Eftersom offer utförs n-st gånger och poll också n-st gånger fås en komplexitet på O(n log(n)). Används istället heapify fås en effektivare algoritm. Har man tillgång till vektorn kan man sortera direkt i den med hjälp av succesiva poll, se figur 29. Figur 29: Effektiv sortering direkt i heapens vektor. I texten ovan används hela tiden en heap med minsta elementet i roten, en min-heap. Definierar man istället roten till att innehålla det största elementet i alla subträd fås en max-heap. 52

53 16.4 Heapsort Först utförs heapify men med max-heap som definition: Figur 30: Heapify ger en vektor [150, 130, 90, 10, 80, 20]. Efter heapify: tag det första (det största) noden ur vektorn och byt plats på det och den sista noden (noden på position n 1). De n 1 första noderna i vektorn representerar nu trädet: Figur 31: Heapify och ett första-sista byte ger vektor/träd ovan. Därefter återställs ordningen med ännu ett anrop av percolatedown-funktionen: Sedan upprepas Figur 32: Heapify och ett första-sista byte och percolate down igen ger vektor/träd ovan. proceduren genom att man tar elementet på position n 2 och byter det med det största (det första) elementet i vektorn. Då har man en vektor [20, 80, 90, , 150], där de sista två elementen är sorterade. Därefter upprepas percolatedown som återställer heap ordningen och element n 3 och det första byts. Algoritmen fortgår tills hela trädet förflyttas till sen sorterade högersidan. Heapsort 53

54 har i värsta fall tidskomplexiteten O(n log(n)). Efter k-steg är de k största elementen sorterade, man kan då avbryta om man vill Alternativa prioritetsköer Ett alternativ till heapar för att implementera prioritetsköer är att använda binära sökträd, då krävs dock att prioriteterna är unika, alternativt får man göra en vektor med listor på varje position,j, där listorna innehåller alla element med prioritet j. Många implementationer av prioritetsköer har ytterligare metoder för att öka-/minska prioriteten på ett element. I så fall måste heapen, om en sådan används, byggas ut så elementen som sätts in innehåller information om vilken plats i vektorn de befinner sig på. 17 Sortering Sortering används huvudsakligen för att göra sökning snabbare och för att förenkla vissa algoritmer. I klassen java.util.arrays finns metoder för sortering av vektorer bestående av element av typen int eller Object. I java collections finns metoder för sortering av listor Urvalssortering Vid urvalssortering söks det minsta elementet i vektorn fram, detta får sedan byta plats med det första elementet. Därefter upprepas sökningen i vektorns osorterade område (andra elementet och uppåt), varpå det minsta elementet får byta plats med vektorns andra element. Detta upprepas tills vektorn är helt sorterad, se figur 33. Urvalssorteringsalgoritmen har en tidskomplexitet på: n 1 + n = O(n 2 ). Figur 33: Urvalssortering illustrerad. En effektivare variant av urvalssortering är den som utförs av heapsort eller med prioritetskö i det tidigare avsnittet Insättningssortering Elementet på plats k, för vardera k 1, 2...n, sätts in på rätt plats bland de redan sorterade elementen, på platserna 0...k 1, se figur 34. Insättningssortering har också den tidskomplexitet O(n 2 ), effektivare i det fall att datan redan är delvis sorterad. 54

55 Figur 34: Insättningssortering illustrerad Insättningssortering implementerad p u b l i c s t a t i c <T extends Comparable<? super T>> void s o r t (T [ ] a ) { f o r ( i n t i = 1 ; i < a. l ength ; i++) { T nextval = a [ i ] ; i n t nextpos = i ; while ( nextpos > 0 && nextval. compareto ( a [ nextpos 1]) <0){ nextpos ; a [ nextpos ]= nextval ; 17.3 Mergesort Mergesort är en divide-conquer algoritm för sortering. Först delas datan upp i två eller flera halvor vilka sorteras var för sig, slutligen slås de samman i en sista sortering. Algoritmen för samsorteringen visas här nedanför: i = j = k = 0 jämför elementet i v1 [ i ] med elementet i v2 [ j ] om det minsta elementet är f r å n v1 r e s [ k ] = v1 [ i ] i=i +1 annars r e s [ k ] = v2 [ j ] j=j+1 k=k+1 upprepa t i l l s a l l a element i en av f ö l j d e r n a har behandlats f l y t t a a l l a element f r å n den andra f ö l j d e n t i l l r e s. Det går alltså inte att utföra sorteringen i den ursprungliga vektorn utan en hjälpvektor, som är stor nog, måste införas. De två minsta elementen i v1 och v2 jämförs och den minsta lagras i resvektorn. Därefter jämför vi nästa element i den vektorn som innehöll det minsta elementet med det minsta i den andra vektorn, det minsta av de två sätts in på nästa plats i res-vektorn. Detta upprepas tills den ena av v1,v2 är tom, då flyttas resten av elementen från den icke tomma av v1,v2 till res. 55

56 Antag att vi har en osorterad vektor. Vi delar upp vektorn på mitten gång på gång (rekursivt) tills delarnas längd är 1. Därefter använder vi samsorterings algoritmen ovan för att jämföra två element åt gången, vilket resulterar i nya sorterade vektorer med 2 element i varje. Därefter samsorterar vi dessa 2-elements vektorer och får sorterade 4-elements vektorer. Dessa samsorteras vidare till 8, och så vidare tills vi har en hel vektor igen, se figur 35 som illustrerar algoritmen steg för steg Figur 35: Mergesort på en vektor med 8 element, först uppdelad i rekursionen för att sedan åter falla samman Mergesort implementerad p r i v a t e s t a t i c <T extends Comparable<? super T>> void merge (T [ ] a, T [ ] tmparray, i n t l e f t P o s, i n t rightpos, i n t rightend ) { i n t leftend = rightpos 1 ; i n t tmppos = l e f t P o s ; while ( l e f t P o s <= leftend && rightpos <= rightend ) { i f ( a [ l e f t P o s ]. compareto ( a [ rightpos ] ) < 0) { tmparray [ tmppos ] = a [ l e f t P o s ] ; l e f t P o s ++; e l s e { tmparray [ tmppos ] = a [ rightpos ] ; rightpos++; tmppos++; / Nu är en av d e l v e k t o r e r n a tom. Kopiera över r e s t e n av elementen i den i c k e tomma vektorn t i l l tmparray / / Flytta t i l l s i s t t i l l b a k s elementen f r å n tmparray t i l l motsvarande p l a t s e r i a / 56

57 / S o r t e r a r elementen i vektora a / p u b l i c s t a t i c <T extends Comparable<? super T>> void s o r t (T [ ] a ) { T [ ] tmparray = (T [ ] ) new Comparable [ a. length ] ; mergesort ( a, tmparray, 0, a. l ength 1 ) ; p r i v a t e s t a t i c <T extends Comparable<? super T>> void mergesort (T [ ] a, T [ ] tmparray, i n t f i r s t, i n t l a s t ) { i f ( f i r s t < l a s t ) { i n t mid = ( f i r s t + l a s t ) / 2 ; mergesort ( a, tmparray, f i r s t, mid ) ; mergesort ( a, tmparray, mid + 1, l a s t ) ; merge ( a, tmparray, f i r s t, mid + 1, l a s t ) ; Tidskomplexitet Att samsortera två sorterade delvektorer av storlek n/2. kostar n. Att mergea två delvektorer av storlek n/2, kostar n Att mergea två delvektorer av storlek n/4 två gånger kostar 2 n/2 = n Att mergea två delvektorer av storlek n/8 fyra gånger kostar 4 n/4 = n. Detta ger att för en vektor av storlek n, som då har log(n) nivåer, kostar O(n log(n)) 17.4 Quicksort Algoritmen quicksort bygger också den på divide-conquer teknik. Den är i värsta fall sämre än mergesort och heapsort, men bättre i medelfall och är därför intressant Algoritm för quicksort Quicksort algoritmen startar med att välja ut ett pivot-element, vilket den ser till att lägga på rätt plats i vektorn genom att flytta alla mindre element till vänster om pivot-elementet och alla större element till höger, detta kallas partitionering. Metodiken upprepas därefter rekursivt i delvektorerna till vänster och höger om pivot-elementet. 57

58 Exempel 20 (Quicksort algoritmens partitioneringssteg) Partitioneringen går till så här: Sök från vänster och upp till pivot alla element som är > pivot. Sök från höger om pivot och uppåt alla element som är pivot. Byt plats på dessa element. Fortsätt till hela vektorn behandlats. Pivot elementet kan sedan sättas in mellan de två vektordelarna som uppstår. Se figur 36 här nedanför för illustration av partitioneringsprocessen. Figur 36:. Efter rekursiv partitionering sorteras delvektorerna a[low]... a[i-1] och a[i+1]... a[high] rekursivt Implementering p u b l i c s t a t i c <T extends Comparable<? super T>> void s o r t (T [ ] a ) { quicksort ( a, 0, a. l e ngth 1 ) ; // Privat r e k u r s i v hjälpmetod som s o r t e r a r d e l v e k t o r n a [ f i r s t ].. a [ l a s t ] : p r i v a t e s t a t i c <T extends Comparable<? super T>> void quicksort (T [ ] a, i n t f i r s t, i n t l a s t ) { i f ( f i r s t < l a s t ) { i n t pivindex = p a r t i t i o n ( a, f i r s t, l a s t ) ; quicksort ( a, f i r s t, pivindex 1 ) ; quicksort ( a, pivindex + 1, l a s t ) ; 58

59 Tidskomplexitet Den effektivaste quicksort algoritmen fås när vektorn delas upp mitt itu i varje rekursivt steg. Då fås tidskomplexiteten O(n log(n)). Sämsta fallet fås då den ena delvektorn blir tom i varje rekursivt steg, då är tidskomplexiteten O(n 2 ) Val av pivotelement För att undvika riskerna för sämsta tidskomplexitet väljs pivot elementet som medianen mellan första-, mittersta- och sista elementet, se figure för tillvägagångssätt. Först sorteras de tre elementen efter storleks ordning, därefter placeras det mellersta av de tre på första platsen i vektorn så att partitionering kan utföras som i exemplen ovan. Figur 37: Medianen hamnar i mitten elementet då de tre markerade elementen jämförs. Figur 38: Därefter läggs medianen på första plats Förbättringar Efter partitioneringen sorteras delvektorerna a[low]... a[i-1] och a[i+1]... a[high] rekursivt. I praktiken låter man av effektivitetsskäl metoden avstanna när delvektorn i det rekursiva anropet är mindre än 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. 18 Sorterings algoritmer i sammanfattning Urvalssortering O(n 2 ): Långsam för stora n. Efter k pass är de k minsta sorterade. Insättningssortering O(n 2 ): Bra för nästan sorterad indata (linjär då). Heapssort O(n log(n)): Kan utformas så att inget extra minnesutrymme krävs. I praktiken långsammare än Quicksort. Efter k pass är de k största elementen sorterade. 59

60 Mergesort O(n log(n)): Kräver extra minnesutrymme. I praktiken långsammare än Quicksort. Kan utformas iterativt och användas för att sortera element som finns på fil. Quicksort O(n log(n)): Men O(n2) i värsta fall. Inget extra minnesutrymme för temporär vektor krävs. Bäst av de nämnda i praktiken om man väljer pivot och utför partitionering förnuftigt. 19 Bevis: Appendix 1 (Bevis) Bevisa att (n 1) = n(n 1) 2. Visualisera summan som trianglar av punkter, se figur 39 Lägg i hop 2 likadana trianglar så en rektangel med dimensionerna n (n 1) bildas: Figur 39: Summa som trianglar. Eftersom vi la ihop två trianglar motsvarar rektangeln dubbla summan. Alltså är summan n(n 1) 2 Appendix 2 (Testa AVL strukturen online) 60

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 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande: Föreläsning 7 Innehåll Rekursion Rekursivt tänkande: Hur många år fyller du? Ett år mer än förra året! Rekursion Rekursiv problemlösning Binärsökning Generiska metoder Rekursiv problemlösning: Dela upp

Läs mer

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

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp Föreläsning 4 Innehåll Abstrakta datatypen lista Definition Abstrakta datatypen lista egen implementering Datastrukturen enkellänkad lista Nästlade klasser statiska nästlade klasser inre klasser Listklasser

Läs mer

Föreläsning 3 Innehåll. Generiska klasser. Icke-generisk lista ArrayList, skiss av implementering. Icke-generisk lista Risk för fel

Föreläsning 3 Innehåll. Generiska klasser. Icke-generisk lista ArrayList, skiss av implementering. Icke-generisk lista Risk för fel Föreläsning 3 Innehåll Generiska klasser Implementera generiska klasser Exceptions Dokumentationekommentarer javadoc Enhetstestning - junit Man kan deklarera en eller flera typparametrar när man definierar

Läs mer

Föreläsning 9 Innehåll

Föreläsning 9 Innehåll Föreläsning 9 Innehåll Binära sökträd algoritmer för sökning, insättning och borttagning, implementering effektivitet balanserade binära sökträd, AVL-träd Abstrakta datatyperna mängd (eng. Set) och lexikon

Läs mer

Programmering fortsättningskurs

Programmering fortsättningskurs Programmering fortsättningskurs Philip Larsson 2013 03 09 Innehåll 1 Träd 1 1.1 Binära träd........................................ 1 1.2 Strikt binärt träd..................................... 1 1.3 Binärt

Läs mer

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

ADT Kö. Seminarium 4 Köer och Stackar Innehåll. Operationer. ADT Stack. Definition. Definition Seminarium 4 Köer och Stackar Innehåll ADT:erna Kö och Stack Definitioner Operationer Exempel på användning Givna klasser i Java Interfacet Queue Klassen Stack Klassen LinkedList Klassen PriorityQueue

Läs mer

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

Föreläsning 6 Innehåll. Rekursion. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursiv problemlösning. Rekursion. Rekursivt tänkande: Föreläsning 6 Innehåll Rekursion Begreppet rekursion Rekursiv problemlösning Samband mellan rekursion och induktion Söndra-och-härska-algoritmer Dynamisk programmering Undervisningsmoment: föreläsning

Läs mer

Föreläsning 4 Innehåll

Föreläsning 4 Innehåll Föreläsning 4 Innehåll Abstrakta datatypen lista Datastrukturen enkellänkad lista Nästlade klasser statiskt nästlade klasser inre klasser Listklasser i Java Implementera abstrakta datatyperna stack och

Läs mer

Seminarium 3 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Seminarium 3 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist. Seminarium 3 Introduktion till Java Collections Framework Innehåll Generik Bakgrund Java Collections Framework interface och klasser för samlingar av element interfacen Iterator och Iterable och foreach-sats

Läs mer

Seminarium 2 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist.

Seminarium 2 Introduktion till Java Collections Framework Innehåll. Generik Bakgrund. Exempel på en generisk klass java.util.arraylist. Seminarium 2 Introduktion till Java Collections Framework Innehåll Generik Bakgrund Generik används för att få typsäkra datastrukturer Java Collections Framework Standardbibliotek med datastrukturer i

Läs mer

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet. -Algoritmer och Datastrukturer- Abstrakt datatyp Datatyp för en variabel Betecknar i ett programmeringsspråk den mängd värden variabeln får anta. T ex kan en variabel av typ boolean anta värdena true och

Läs mer

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

Föreläsning 7. Träd och binära sökträd Föreläsning 7 Träd och binära sökträd Föreläsning 7 Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning Läsanvisningar och

Läs mer

Länkade strukturer. (del 2)

Länkade strukturer. (del 2) Länkade strukturer (del 2) Översikt Abstraktion Dataabstraktion Inkapsling Gränssnitt (Interface) Abstrakta datatyper (ADT) Programmering tillämpningar och datastrukturer 2 Abstraktion Procedurell abstraktion

Läs mer

Föreläsning 5 Innehåll

Föreläsning 5 Innehåll Föreläsning 5 Innehåll Algoritmer och effektivitet Att bedöma och jämföra effektivitet för algoritmer Begreppet tidskomplexitet Datavetenskap (LTH) Föreläsning 5 VT 2019 1 / 39 Val av algoritm och datastruktur

Läs mer

Föreläsning 3 Innehåll

Föreläsning 3 Innehåll Föreläsning 3 Innehåll Jämföra element interfacen Comparable och och Comparator Implementera generiska klasser Exceptions Dokumentationekommentarer javadoc Enhetstestning - junit Datavetenskap (LTH) Föreläsning

Läs mer

Diskutera Sortera objekt

Diskutera Sortera objekt Föreläsning 3 Innehåll Diskutera Sortera objekt Metoden sort är en statisk metod i klassen Arrays. Den sorterar vektorn som skickas med som argument. Jämföra element interfacen Comparable och och Comparator

Läs mer

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

Hitta k största bland n element. Föreläsning 13 Innehåll. Histogramproblemet Föreläsning 13 Innehåll Algoritm 1: Sortera Exempel på problem där materialet i kursen används Histogramproblemet Schemaläggning Abstrakta datatyper Datastrukturer Att jämföra objekt Om tentamen Skriftlig

Läs mer

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki Föreläsning 2 Innehåll Java Collections Framework (interface och klasser för samlingar av element) Använda generiska klasser autoboxing - och unboxing Iterera genom en samling element Jämföra element skugga

Läs mer

Föreläsning 2 Innehåll

Föreläsning 2 Innehåll Föreläsning 2 Innehåll Java Collections Framework (interface och klasser för samlingar av element) Använda generiska klasser autoboxing - och unboxing Iterera genom en samling element Jämföra element skugga

Läs mer

Föreläsning 14 Innehåll

Föreläsning 14 Innehåll Föreläsning 14 Innehåll Abstrakta datatyper, datastrukturer Att jämföra objekt övriga moment i kursen Om tentamen Skriftlig tentamen både programmeringsuppgifter och teoriuppgifter Hitta fel i fingerade

Läs mer

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

Föreläsning 5 Innehåll. Val av algoritm och datastruktur. Analys av algoritmer. Tidsåtgång och problemets storlek Föreläsning 5 Innehåll Val av algoritm och datastruktur Algoritmer och effektivitet Att bedöma och jämföra effektivitet för algoritmer Begreppet tidskomplexitet Det räcker inte med att en algoritm är korrekt

Läs mer

Föreläsning 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna

Föreläsning 10 Innehåll. Prioritetsköer och heapar. ADT Prioritetskö. Interface för Prioritetskö. Exempel på vad du ska kunna Föreläsning Innehåll Prioritetsköer och heapar Prioritetsköer och heapar ADT prioritetskö Klassen PriorityQueue i java.util Implementering med lista ar Implementering av prioritetskö med heap Sortering

Läs mer

Föreläsning 10 Innehåll

Föreläsning 10 Innehåll Föreläsning 10 Innehåll Binära sökträd algoritmer för sökning, insättning och borttagning implementering effektivitet balanserade binära sökträd, AVL-träd Jämföra objekt interfacet Comparable Interfacet

Läs mer

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition

Föreläsning 10 Innehåll. Diskutera. Inordertraversering av binära sökträd. Binära sökträd Definition Föreläsning Innehåll Diskutera Binära sökträd algoritmer för sökning, insättning och borttagning implementering effektivitet balanserade binära sökträd, AVL-träd Jämföra objekt interfacet Comparable Interfacet

Läs mer

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 2 Datastrukturer (DAT037) Föreläsning 2 Datastrukturer (DAT037) Fredrik Lindblad 1 2016-11-02 1 Slides skapade av Nils Anders Danielsson har använts som utgångspunkt. Se http://www.cse.chalmers.se/edu/year/2015/course/dat037 Tidskomplexitet

Läs mer

Föreläsning 2 Innehåll

Föreläsning 2 Innehåll Föreläsning 2 Innehåll Java Collections Framework (interface och klasser för samlingar av element) Använda generiska klasser autoboxing - och unboxing Iterera genom en samling element Jämföra element skugga

Läs mer

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer Arrayer Samling av data Datastrukturer int[] minatelnummer = new int[30]; // allokering av tillräckligt // stort minnesutrymme Element refereras genom indexering ringa = minatelnummer[25]; // indexering

Läs mer

Samlingar Collection classes

Samlingar Collection classes Samlingar Collection classes Sven-Olof Nyström Uppsala Universitet 17 mars 2005 Skansholm: Kapitel 9, 19 Se även Suns tutorial om Collections Olika slag av samlingar i Java Arrayer (Till exempel: int[])

Läs mer

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd

Föreläsning 11 Innehåll. Diskutera. Binära sökträd Definition. Inordertraversering av binära sökträd Föreläsning Innehåll Diskutera Binära sökträd algoritmer för sökning, insättning och borttagning implementering effektivitet balanserade binära sökträd, AVL-träd Jämföra objekt interfacet Comparable Interfacet

Läs mer

Interfacen Set och Map, hashtabeller

Interfacen Set och Map, hashtabeller Föreläsning 0 Innehåll Hashtabeller implementering, effektivitet Interfacen Set och Map ijava Interfacet Comparator Undervisningsmoment: föreläsning 0, övningsuppgifter 0-, lab 5 och 6 Avsnitt i läroboken:

Läs mer

Diskutera. Hashfunktion

Diskutera. Hashfunktion Föreläsning 1 Innehåll Diskutera Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map i Java Tidigare har

Läs mer

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

ADT Prioritetskö. Föreläsning 13 Innehåll. Prioritetskö vs FIFO-kö. Prioritetskö Exempel på användning. Prioritetsköer och heapar Föreläsning 1 Innehåll ADT Prioritetskö Prioritetsköer och heapar Prioritetsköer och heapar ADT prioritetskö Klassen PriorityQueue i java.util ar Implementering av prioritetskö med heap Sortering med hjälp

Läs mer

Föreläsning 10. ADT:er och datastrukturer

Föreläsning 10. ADT:er och datastrukturer Föreläsning 10 ADT:er och datastrukturer ADT:er och datastrukturer Dessa två begrepp är kopplade till varandra men de står för olika saker. En ADT (abstrakt datatyp) är just abstrakt och är inte kopplad

Läs mer

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki

Java Collections Framework. Föreläsning 2 Innehåll. Java Collections Framework interface hierarki. Java Collections Framework interface hierarki Föreläsning 2 Innehåll Java Collections Framework (interface och klasser för samlingar av element) Använda generiska klasser autoboxing - och unboxing Iterera genom en samling element Jämföra element skugga

Läs mer

Tentamen Programmeringsteknik II och NV2 (alla varianter) 2008-12-10. Skriv bara på framsidan av varje papper.

Tentamen Programmeringsteknik II och NV2 (alla varianter) 2008-12-10. Skriv bara på framsidan av varje papper. Tentamen Programmeringsteknik II och NV2 (alla varianter) 2008-12-10 Skrivtid: 0800-1300 Inga hjälpmedel. Tänk på följande Maximal poäng är 40. För betygen 3 krävs 18 poäng. För betygen 4, 5 kommer något

Läs mer

Föreläsning 2 Innehåll. Generiska klasser. Generik i Java. Varför generiska klasser Bakgrund

Föreläsning 2 Innehåll. Generiska klasser. Generik i Java. Varför generiska klasser Bakgrund Föreläsning 2 Innehåll Generiska klasser Javas samlingsklasser är generiska. Använda generiska klasser autoboxing - och unboxing Iterera genom en samling element Jämföra element metoden equals En generisk

Läs mer

Programmering för språkteknologer II, HT2014. evelina.andersson@lingfil.uu.se Rum 9-2035 http://stp.ling.uu.se/~evelina/uv/uv14/pst2/

Programmering för språkteknologer II, HT2014. evelina.andersson@lingfil.uu.se Rum 9-2035 http://stp.ling.uu.se/~evelina/uv/uv14/pst2/ Programmering för språkteknologer II, HT2014 Avancerad programmering för språkteknologer, HT2014 evelina.andersson@lingfil.uu.se Rum 9-2035 http://stp.ling.uu.se/~evelina/uv/uv14/pst2/ Idag - Hashtabeller

Läs mer

Föreläsning 10 Innehåll

Föreläsning 10 Innehåll Föreläsning 10 Innehåll Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map i Java Undervisningsmoment:

Läs mer

Föreläsning 6: Introduktion av listor

Föreläsning 6: Introduktion av listor Föreläsning 6: Introduktion av listor Med hjälp av pekare kan man bygga upp datastrukturer på olika sätt. Bland annat kan man bygga upp listor bestående av någon typ av data. Begreppet lista bör förklaras.

Läs mer

Seminarium 13 Innehåll

Seminarium 13 Innehåll Seminarium 13 Innehåll Prioritetsköer och heapar Prioritetsköer ADTn Klassen PriorityQueue i java.util Implementering med lista Heapar ADTn För implementering av prioritetskö För sortering Efter seminariet

Läs mer

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

Algoritmer och effektivitet. Föreläsning 5 Innehåll. Analys av algoritmer. Analys av algoritmer Tidskomplexitet. Algoritmer och effektivitet Föreläsning 5 Innehåll Algoritmer och effektivitet Algoritmer och effektivitet Att bedöma, mäta och jämföra effektivitet för algoritmer Begreppet tidskomplexitet Undervisningsmoment: föreläsning 5, övningsuppgifter

Läs mer

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander

F12 - Collections. ID1004 Objektorienterad programmering Fredrik Kilander F12 - Collections ID1004 Objektorienterad programmering Fredrik Kilander fki@kth.se Collections (samlingar) En collection är ett objekt som fungerar som en samling av andra objekt En collection erbjuder

Läs mer

DAT043 - föreläsning 8

DAT043 - föreläsning 8 DAT043 - föreläsning 8 Paket, generics, Java collections framework 2017-02-07 Paket och tillgänglighet Ovanför klasser finns en hierarkisk namespace med paket. Filer som inte deklareras i något paket finns

Läs mer

Föreläsning 10 Innehåll. Diskutera. Hashtabeller. Hashfunktion. hashfunktion. hashkod (ett heltal)

Föreläsning 10 Innehåll. Diskutera. Hashtabeller. Hashfunktion. hashfunktion. hashkod (ett heltal) Föreläsning 0 Innehåll Diskutera Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map ijava Undervisningsmoment:

Läs mer

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

ADT Prioritetskö. Föreläsning 12 Innehåll. Prioritetskö. Interface för Prioritetskö. Prioritetsköer och heapar Föreläsning 1 Innehåll Prioritetsköer och heapar Prioritetsköer och heapar ADT prioritetskö Klassen PriorityQueue i java.util Heapar Implementering av prioritetskö med heap Sortering med hjälp av heap

Läs mer

Inlämningsuppgift och handledning

Inlämningsuppgift och handledning Inlämningsuppgift och handledning Inlämningsuppgiften redovisas i vecka 49/50. Hög tid att komma igång! Jourtider varje vecka (se http://cs.lth.se/edaa01ht/inlaemningsuppgift) Frågestunder på fredagluncher

Läs mer

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

Programmering för Språkteknologer II. Innehåll. Associativa datastrukturer. Associativa datastrukturer. Binär sökning. Programmering för Språkteknologer II Markus Saers markus.saers@lingfil.uu.se Rum -040 stp.lingfil.uu.se/~markuss/ht0/pst Innehåll Associativa datastrukturer Hashtabeller Sökträd Implementationsdetaljer

Läs mer

Objektsamlingar i Java

Objektsamlingar i Java 1 (6) Objektsamlingar i Java Objektorienterad programmering 3 Syfte Att ge träning i att använda objektsamlingar i Java. Mål Efter övningen skall du kunna använda objektsamlingsklasserna ArrayList och

Läs mer

Stackar, köer, iteratorer och paket

Stackar, köer, iteratorer och paket Stackar, köer, iteratorer och paket Programmering för språkteknologer 2 Sara Stymne 2013-09-18 Idag Paket Stackar och köer Array resp länkad struktur Iteratorer Javadoc Kommentarer lab 1 Bra att de flesta

Läs mer

Länkade strukturer, parametriserade typer och undantag

Länkade strukturer, parametriserade typer och undantag Länkade strukturer, parametriserade typer och undantag Programmering för språkteknologer 2 Sara Stymne 2013-09-18 Idag Parametriserade typer Listor och länkade strukturer Komplexitet i länkade strukturer

Läs mer

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4

Träd, binära träd och sökträd. Koffman & Wolfgang kapitel 6, avsnitt 1 4 Träd, binära träd och sökträd Koffman & Wolfgang kapitel 6, avsnitt 1 4 1 Träd Träd är ickelinjära och hierarkiska: i motsats till listor och fält en trädnod kan ha flera efterföljare ( barn ) men bara

Läs mer

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material)

Objektorienterad Programmering DAT043. Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material) Objektorienterad Programmering DAT043 Föreläsning 9 12/2-18 Moa Johansson (delvis baserat på Fredrik Lindblads material) 1 Metoden clone() Skapa kopior av existerande objekt. Interface Cloneable Deep vs.

Läs mer

Föreläsning 13 och 14: Binära träd

Föreläsning 13 och 14: Binära träd Föreläsning 13 och 14: Binära träd o Binärträd och allmänna träd o Rekursiva tankar för binärträd o Binära sökträd Binärträd och allmänna träd Stack och kö är två viktiga datastrukturer man kan bygga av

Läs mer

Föreläsning 11 Innehåll

Föreläsning 11 Innehåll Föreläsning 11 Innehåll Hashtabeller implementering, effektivitet Metoden hashcode i Java Abstrakta datatyperna mängd (eng. Set) och lexikon (eng. Map) Interfacen Set och Map i Java Datavetenskap (LTH)

Läs mer

Försättsblad till skriftlig tentamen vid Linköpings Universitet

Försättsblad till skriftlig tentamen vid Linköpings Universitet Försättsblad till skriftlig tentamen vid Linköpings Universitet Datum för tentamen 2016-03-21 Sal Tid 08:00 12:00 Kurskod Provkod Kursnamn/benämning Institution Antal uppgifter som ingår i tentamen Antal

Läs mer

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

6 Rekursion. 6.1 Rekursionens fyra principer. 6.2 Några vanliga användningsområden för rekursion. Problem löses genom: 6 Rekursion 6.1 Rekursionens fyra principer Problem löses genom: 1. förenkling med hjälp av "sig själv". 2. att varje rekursionssteg löser ett identiskt men mindre problem. 3. att det finns ett speciellt

Läs mer

Tentamen Datastrukturer D DAT 036/DIT960

Tentamen Datastrukturer D DAT 036/DIT960 Tentamen Datastrukturer D DAT 036/DIT960 17 december 2010 Tid: 8.30-12.30 Ansvarig: Peter Dybjer, tel 0736-341480 eller ankn 1035 Max poäng på tentamen: 60. Betygsgränser, CTH: 3 = 24 p, 4 = 36 p, 5 =

Läs mer

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

Objektorienterad Programkonstruktion. Föreläsning 9 30 nov 2016 Objektorienterad Programkonstruktion Föreläsning 9 30 nov 2016 Collections Ett samlingsnamn på objekt som innehåller en samling av andra objekt Det finns många olika sorters Collections, t.ex listor, träd,

Läs mer

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl 9.00 14.

Tentamen. 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl 9.00 14. Tentamen 2D4135 vt 2005 Objektorienterad programmering, design och analys med Java Lördagen den 28 maj 2005 kl 9.00 14.00, sal E33 Tentan har en teoridel och en problemdel. På teoridelen är inga hjälpmedel

Läs mer

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass

EDAA20 Föreläsning Klassen ArrayList. Viktiga operationer på ArrayList. Generisk klass EDAA20 Föreläsning 11-12 Klassen ArrayList Klassen ArrayList Skriva program som läser data från en textfil och skriver data till en textfil Repetition inför delmålskontroll 2 är en standardklass (i paketet

Läs mer

Tentamen TEN1 HI1029 2014-05-22

Tentamen TEN1 HI1029 2014-05-22 Tentamen TEN1 HI1029 2014-05-22 Skrivtid: 8.15-13.00 Hjälpmedel: Referensblad (utdelas), papper (tomma), penna Logga in med tentamenskontot ni får av skrivvakten. Det kommer att ta tid att logga in ha

Läs mer

Sätt att skriva ut binärträd

Sätt att skriva ut binärträd Tilpro Övning 3 På programmet idag: Genomgång av Hemtalet samt rättning Begreppet Stabil sortering Hur man kodar olika sorteringsvilkor Inkapsling av data Länkade listor Användning av stackar och köer

Läs mer

Inlämningsuppgift och handledning. Föreläsning 11 Innehåll. Diskutera. Hashtabeller

Inlämningsuppgift och handledning. Föreläsning 11 Innehåll. Diskutera. Hashtabeller Inlämningsuppgift och handledning Föreläsning 11 Innehåll Inlämningsuppgiften redovisas i vecka 49/50. Hög tid att komma igång! Jourtider varje vecka (se http://cs.lth.se/edaa01ht/inlaemningsuppgift) Frågestunder

Läs mer

Föreläsning 9 Innehåll

Föreläsning 9 Innehåll Föreläsning 9 Innehåll Träd, speciellt binära träd egenskaper användningsområden implementering Datavetenskap (LTH) Föreläsning 9 HT 2017 1 / 31 Inlämningsuppgiften De föreläsningar som inlämningsuppgiften

Läs mer

Datastrukturer. föreläsning 3. Stacks 1

Datastrukturer. föreläsning 3. Stacks 1 Datastrukturer föreläsning 3 Stacks 1 Abstrakta datatyper Stackar - stacks Köer - queues Dubbeländade köer - deques Vektorer vectors (array lists) All är listor men ger tillgång till olika operationer

Läs mer

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor Abstrakta datatyper 1 Primitiva vektorer Vektorer kan skapas av primitiva datatyper, objektreferenser eller andra vektorer. Vektorer indexeras liksom i C från 0. För att referera en vektor används hakparenteser.

Läs mer

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2 Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket 1 Länkade listor Likadant som i Ada-kursen. 2 Stack MyStack MyStack

Läs mer

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

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Jonas Lindgren, Institutionen för Datavetenskap, LiU TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 8 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Träd Traversering Insättning, borttagning

Läs mer

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall

SCB :-0. Uno Holmer, Chalmers, höger 2 Ex. Induktiv definition av lista. // Basfall Rekursiva funktioner Föreläsning 10 (Weiss kap. 7) Induktion och rekursion Rekursiva funktioner och processer Weiss 7.1-3 (7.4, 7.5.3 utgår) Fibonaccital (7.3.4) Exempel: Balansering av mobil (kod se lab

Läs mer

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen Föreläsning 9 Innehåll Inlämningsuppgiften De föreläsningar som inlämningsuppgiften bygger på är nu klara. Det är alltså dags att börja arbeta med inlämningsuppgiften. Träd, speciellt binära träd egenskaper

Läs mer

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

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Abstrakta datatyper Listor Stackar

Läs mer

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd Föreläsning 8 Innehåll Datastrukturer i kursen Träd, speciellt binära träd egenskaper användningsområden implementering Undervisningsmoment: föreläsning 8, övningsuppgifter 8, lab 4 Avsnitt i läroboken:

Läs mer

Föreläsning 9 Datastrukturer (DAT037)

Föreläsning 9 Datastrukturer (DAT037) Föreläsning Datastrukturer (DAT07) Fredrik Lindblad 27 november 207 Slides skapade av Nils Anders Danielsson har använts som utgångspunkt Se http://wwwcsechalmersse/edu/year/20/course/dat07 Innehåll 2

Läs mer

Föreläsning 3. Stack

Föreläsning 3. Stack Föreläsning 3 Stack Föreläsning 3 ADT Stack Stack JCF Tillämpning Utvärdera ett postfix uttryck Stack implementerad med en array Stack implementerad med en länkad lista ADT Stack Grundprinciper: En stack

Läs mer

Objektorienterad programmering D2

Objektorienterad programmering D2 Objektorienterad programmering D2 Laboration nr 2. Syfte Att få förståelse för de grundläggande objektorienterade begreppen. Redovisning Källkoden för uppgifterna skall skickas in via Fire. För senaste

Läs mer

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Laboration 2 Datastrukturer En liten uppgift Frågor

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Laboration 2 Datastrukturer En liten uppgift Frågor TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2 Laboration 2 Datastrukturer En liten uppgift Frågor 1 Laboration 2 - Datastrukturer Länkade datastrukturer Stack Kö (En. Queue) Lista

Läs mer

Föreläsning Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT036) Föreläsning Datastrukturer (DAT036) Nils Anders Danielsson 2013-11-25 Idag Starkt sammanhängande komponenter Duggaresultat Sökträd Starkt sammanhängande komponenter Uppspännande skog Graf, och en möjlig

Läs mer

Begreppet subtyp/supertyp i Java. Mera om generik. Generik och arv. Generik och arv. Innehåll

Begreppet subtyp/supertyp i Java. Mera om generik. Generik och arv. Generik och arv. Innehåll Mera om generik Begreppet subtyp/supertyp i Java Innehåll Wildcards Vektorer och generik Supertyper för en viss klass C är alla klasser från vilka C ärver och alla interface som klassen implementerar.

Läs mer

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm.

Algoritmanalys. Genomsnittligen behövs n/2 jämförelser vilket är proportionellt mot n, vi säger att vi har en O(n) algoritm. Algoritmanalys Analys av algoritmer används för att uppskatta effektivitet. Om vi t. ex. har n stycken tal lagrat i en array och vi vill linjärsöka i denna. Det betyder att vi måste leta i arrayen tills

Läs mer

Föreläsning 4: Kombinatorisk sökning

Föreläsning 4: Kombinatorisk sökning DD2458, Problemlösning och programmering under press Föreläsning 4: Kombinatorisk sökning Datum: 2009-09-25 Skribent(er): Kristina Nylander, Dennis Ekblom, Marcus Öman Föreläsare: Fredrik Niemelä 1 Introduktion

Läs mer

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

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Abstrakta datatyper Listor Stackar

Läs mer

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

Föreläsning 2. Länkad lista och iterator Föreläsning 2 Länkad lista och iterator Föreläsning 2 Länkad-lista Lista implementerad med en enkellänkad lista Iterator Implementering av en Iterator Dubbellänkad lista och cirkulär lista LinkedList JCF

Läs mer

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en Tentamen Programmeringsteknik II 2017-10-23 Skrivtid: 14:00 19:00 Inledning Skrivningen innehåller ett antal bilagor: Bilagan listsandtrees innehåller fyra klasser: Klassen List med några grundläggande

Läs mer

Föreläsning 2 Datastrukturer (DAT037)

Föreläsning 2 Datastrukturer (DAT037) Föreläsning 2 Datastrukturer (DAT037) Fredrik Lindblad 1 1 november 2017 1 Slides skapade av Nils Anders Danielsson har använts som utgångspunkt. Se http://www.cse.chalmers.se/edu/year/2015/course/dat037

Läs mer

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Mer om Interface Generiska klasser Undantag Nästlade klasser 1

Läs mer

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

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 9 Jonas Lindgren, Institutionen för Datavetenskap, LiU På denna föreläsning: Prioritetskö Heap Representation som

Läs mer

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU TDDC30 Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Interface Generiska klasser Undantag

Läs mer

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254

Rekursion. Att tänka rekursivt Att programmera rekursivt i Java Exempel. Programmeringsmetodik -Java 254 Rekursion Rekursion är en grundläggande programmeringsteknik M h a rekursion kan vissa problem lösas på ett mycket elegant sätt Avsnitt 11 i kursboken: Att tänka rekursivt Att programmera rekursivt i Java

Läs mer

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 5 Erik Nilsson, Institutionen för Datavetenskap, LiU På denna föreläsning: Kort om javadoc Abstrakta datatyper Ordböcker/Mappar Listor Stackar

Läs mer

Föreläsning REPETITION & EXTENTA

Föreläsning REPETITION & EXTENTA Föreläsning 18 19 REPETITION & EXTENTA Programmeringsteknik på 45 minuter Klasser och objekt Variabler: attribut, lokala variabler, parametrar Datastrukturer Algoritmer Dessa bilder är inte repetitionsbilder

Läs mer

Föreläsning 4 Datastrukturer (DAT037)

Föreläsning 4 Datastrukturer (DAT037) Föreläsning 4 Datastrukturer (DAT07) Fredrik Lindblad 1 november 2017 1 Slides skapade av Nils Anders Danielsson har använts som utgångspunkt Se http://wwwcsechalmersse/edu/year/2015/course/dat07 1 Innehåll

Läs mer

Rekursion och induktion för algoritmkonstruktion

Rekursion och induktion för algoritmkonstruktion Informationsteknologi Tom Smedsaas, Malin Källén 20 mars 2016 Rekursion och induktion för algoritmkonstruktion Att lösa ett problem rekursivt innebär att man uttrycker lösningen i termer av samma typ av

Läs mer

Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 27 maj 2008

Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 27 maj 2008 Lösningsförslag till tentamen i EDA011/EDA017 Programmeringsteknik för F, E, I, π och N 27 maj 2008 Christian 27 maj 2008 Uppgift 1 Flera av dem jag talade med efter tentan hade blivit förskräckta när

Läs mer

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs

Tentamen, EDAA01 Programmeringsteknik fördjupningskurs LUNDS TEKNISKA HÖGSKOLA 1(3) Institutionen för datavetenskap Tentamen, EDAA01 Programmeringsteknik fördjupningskurs 2017 08 14, 8.00 13.00 Anvisningar: Denna tentamen består av 5 uppgifter. Preliminärt

Läs mer

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg LUNDS TEKNISKA HÖGSKOLA 1(5) Institutionen för datavetenskap Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg 2013 12 19, 8.00 13.00 Anvisningar: Denna tentamen består av 4 uppgifter. Preliminärt

Läs mer

Tentamen i Objektorienterad programmering

Tentamen i Objektorienterad programmering CHALMERS TEKNISKA HÖGSKOLA Datavetenskap TDA547 Tentamen i Objektorienterad programmering Lördagen 12 mars 2011, 8.30 12.30. Jourhavande lärare: Björn von Sydow, tel 0762/981014. Inga hjälpmedel. Lösningar

Läs mer

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

Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs LUNDS TEKNISKA HÖGSKOLA 1(5) Institutionen för datavetenskap Lösningsförslag till tentamen i EDAA01 programmeringsteknik fördjupningkurs 2013 12 19 1. a) En samling element där insättning och borttagning

Läs mer

Tentamen OOP 2015-03-14

Tentamen OOP 2015-03-14 Tentamen OOP 2015-03-14 Anvisningar Fråga 1 och 2 besvaras på det särskilt utdelade formuläret. Du får gärna skriva på bägge sidorna av svarsbladen, men påbörja varje uppgift på ett nytt blad. Vid inlämning

Läs mer

Vad handlar kursen om? Algoritmer och datastrukturer. Vad handlar kursen om? Vad handlar kursen om?

Vad handlar kursen om? Algoritmer och datastrukturer. Vad handlar kursen om? Vad handlar kursen om? Algoritmer och datastrukturer Allmänt om kursen Kort javagrund repetition - Klasser, metoder, objekt och referensvariabler, - Hierarkiska klass strukturer - Arrayer och arrayer av objekt - Collection ramverket

Läs mer

Dugga Datastrukturer (DAT036)

Dugga Datastrukturer (DAT036) Dugga Datastrukturer (DAT036) Duggans datum: 2012-11-21. Författare: Nils Anders Danielsson. För att en uppgift ska räknas som löst så måste en i princip helt korrekt lösning lämnas in. Enstaka mindre

Läs mer