Fundamentale datastrukturer

Slides:



Advertisements
Lignende præsentationer
HUNDE SPEED km h 34,4 HUNDE SPEED km h 34,1 HUNDE SPEED km h 32,8 HUNDE SPEED km h 31,9 HUNDE SPEED km h 31,8 HUNDE SPEED km h 30,9.
Advertisements

Den danske befolknings syn på handicappedes rettigheder
VMS data Geografisk og tidsmæssig udvikling af indsatsen i tobisfiskeriet v/ dataspecialist Josefine Egekvist Sekretariat for myndighedsbetjening.
Atomer Et programmeret forløb. En måde at lære på.
Børns indflydelse på familiens købsbeslutninger
UU-Aalborg Evaluering af brobygning og intro 2013/14 Velkommen UU-Aalborg Ungdommens Uddannelsesvejledning.
Produktionsøkonomi Planteavl 2013
Funktioner Grundbegreber.
Hjemmesidekonstruktion Tjekspørgsmål 1.Hvad er et markup-sprog – hvad bruges det til? 2.Hvad er forskellen mellem et markup-sprog og et scriptsprog? 3.Hvad.
Prospekt. Ideen •Casa della filosofia er navnet på en forening, der giver almin- delige mennesker mulighed for at have brugsret til et hus i Italien på.
Niveauer af abstrakte maskiner
Kap. 2 Fiskeri med trawl 2.1 · En smakke med trawlet ude.
Velkommen til Softwarekonstruktion
v/ Professor Lars Ehlers, Aalborg Universitet
Velkommen hos Juvel A/S
Bolig selskabernes Landsforening– Almene lejeboliger - Maj/Juni Almene lejeboliger - Danmarkspanelet - Maj/Juni 2010.
07 – Kort om OO Introduktion.
Trivselsundersøgelse og ledelsesevaluering
KONCEPT Klasser og objekter En klasse beskriver et World ArrayList
Symbolsk maskinsprog.
Statistik.
Grundlæggende programmering Efterår 2001

Representations for Path Finding in Planar Environments.
Hvordan man skriver koden.
Grundlæggende regnskabsforståelse
HUSKESPIL – den lille tabel
Titel: Arial, fed, skriftstr. 20, mørkegrå. Tekst: Arial, normal, fed eller kursiv, skriftstr. 10, 12 og 14 til print – 16 og 18 til projektor – mørkegrå.
 2 3  3 =  83  43  53  63  73  93  10 4.
Oplæg til Nofa4 i Trondheim d maj 2013 Ved Lektor Rune Christiansen
Pleje og Sundhed Gennemførte719 Inviterede895 Svarprocent80% FREDERICIA KOMMUNE MTU og Psykisk APV 2012 Rapportspecifikationer.
1 UNION-FIND. 2 inddata: en følge af heltalspar (p, q); betydning: p er “forbundet med” q uddata: intet, hvis p og q er forbundet, ellers (p, q) Eksempel.
1 Powerpointserie om In-line færdiggørelse ved Heatsettrykning Avisrotation Magasindybtryk Den Grafiske Højskole.
FEN IntroJava AAU1 Java grundelementer Variable og datatyper Sætninger og udtryk Metoder.
Trivselsundersøgelse og ledelsesevaluering Anæstesiologisk Afdeling Flere ledere
Datastrukturer og Collections Rasmus D. Lehrmann DM
ETU 2008 | Elevtilfredshedsundersøgelse Erhvervsskolen Nordsjælland HTX (Teknisk Gymnasium) - Hillerød Baseret på 313 besvarelser.
1 Datalogi C Datastrukturer og algoritmer ved Keld Helsgaun.
1 Borgerpanelet i Silkeborg Kommune.
Globaliseringsredegørelsen 24.mar. 14 Figurer fra Danmark tiltrækker for få udenlandske investeringer i Sådan ligger landet
1 Sortering I elementære metoder. 2 Plan Terminologi Elementære metoder til sortering -sortering ved udvælgelse -sortering ved indsættelse -Shellsort.
Nye genetiske parametre for ydelse Anders Fogh og Kevin Byskov.
Forelæsning 3.1 Collections Javas for-each løkke
Matematik B 1.
Claus Brabrand, ITU, Denmark Mar 10, 2009EFFECTIVE JAVA Effective Java Presentation Workshop Claus Brabrand [ ] ( “FÅP”: First-year Project.
1 Tråde 2 Plan Trådbegrebet Synkronisering Koordinering Eksempel: et flertrådet spil.
Grunde til at jeg elsker dig
Januar 2009 MandagTirsdagOnsdagTorsdagFredagLørdagSøndag Uge 2. Anette Ø. Kl Tina H. Lone M. 6 Kl Britt H. 7 Kl Vinnie G. Gerda.
Lektion 7 Læsestof: Kopier fra Caranno
1 Grafalgoritmer I. 2 Plan Grafer - definition - anvendelser - terminologi - eksempler på grafproblemer Grafgennemgang - dybde-først-gennemgang - bredde-først-gennemgang.
Objekter og klasser Rasmus D. Lehrmann DM
10. Datastrukturer. 2 Nordjyllands Erhvervakademi Collections library Datastrukturer i.NET kaldes normalt Collections Findes i namespace System.Collections.
1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper : arrays, stakke, køer,
1 Kap. 4, Jordens Tyngdefelt = Torge, 2001, Kap. 3. Tyngdekraftens retning og størrelse g (m/s 2 ) Acceleration Tyngdepotentialet (W): evene til at udføre.
8 RÅD VEDRØRENDE GOD PROGRAMMERING Effective (brown) Java.
KF04 GRAY Item 2, 12, 22, 32, 42, 52. Consider a builder when faced with many constructor parameters Item 2.
03 – Udtryk og metoder. 2 NOEA2009Java-kursus – Udtryk og metoder Udtryk i Java Java har standard udtrykene… Værditildeling Subrutiner og funktionskald.
Længste plateau En klassisk problemstilling (Gries, 1981) - og her i Java!!! Denne opgave drejer sig om at bestemme længden af det længste plateau i en.
Begreber og Redskaber 11. Plan for idag Lidt afrunding: Collections Framework i Java Noget om oversættere og sprog Evaluering Sidste gang øvelser før.
Begreber og Redskaber 4. Plan for idag Om metoder, parametre, returværdier Et par ord om objekt-orientering Håndkøring af programmer.
Begreber og Redskaber 3. Plan for idag Om metoder, parametre, returværdier Overblik over klasser,objekter,nedarvning Et par ord om objekt-orientering.
I o p o DAIMI, AU, November 1999Programkonstruktion I9E.1 Konstruktion og brug af klasser – en stak og en HP-regnemaskine push pop.
Variabler, klassevariabler, identitet og lighed, collections
 Michael E. Caspersen, 2000Introducerende objektorienteret programmering6A.1 Programmering med interfaces – en stak og en HP-regnemaskine push pop.
Interfaces Afkobling af programkomponenter (eksempel: Comparable)
Programmering med interfaces Separering af specifikation, anvendelse og implementation.
Klasser og objekter – grundbegreber.  Michael E. Caspersen, 2001Introducerende objektorienteret programmeringKlasser og objekter.2 Klasser og objekter.
Programmering med interfaces – en stak og en HP-regnemaskine push pop.
 Jens Bennedsen 2001Multimedie programmering4.1 Definition af begreber Interface, implements, klasse.
Præsentationens transcript:

Fundamentale datastrukturer

Plan * Definitioner: abstrakt datatype, datastruktur * Elementære datastrukturer og abstrakte datatyper: arrays, hægtede lister, stakke, køer * Træer: terminologi, egenskaber, repræsentation, gennemgang

Definitioner En type er en samling af værdier. Eks. typen boolean omfatter værdierne true og false En datatype er en type tilknyttet en mængde af operationer på typen. Eks. typen int er en datatype. Addition er et eksempel på en tilknyttet operation. En abstrakt datatype er en datatype, der udelukkende er specificeret ved hjælp af typen og de tilknyttede operationer. Kun operationernes input/output-relationer er specificeret - ikke deres konkrete realisering. Hverken datarepræsentation eller algoritmer må medtages i specifikationen. En abstrakt datatype specificerer ”hvad”, men ikke ”hvordan”.

Abstrakte datatyper En ADT skjuler den konkrete implementation fra anvenderen (klienten). Fordele: (1) Det er lettere at bruge noget, hvis det ikke kræver internt kendskab til virkemåden. Tænk f.eks. på en radio eller en vaskemaskine (2) Den konkrete implementation kan ændres, uden at klienten behøver at få det at vide. Realisering i Java: En ADT kan realiseres som en klasse, hvor data er private. Brug “setters” and “getters” til at ændre og tilgå data.

Datastruktur En datastruktur er en samling variabler, muligvis af forskellig type, der er indbyrdes forbundet på en eller anden måde. Realisering i Java: ved simple variabler, arrays og klasseobjekter

Arrays (to perspektiver) (1) Datastruktur: Et array er en sammenhængende blok af lagerceller, hvor hver lagercelle indeholder et dataelement af en fast længde. celle array

Et array er en samling af dataelementer af (2) Abstrakt datatype: Et array er en samling af dataelementer af samme type, hvor hvert dataelement kan identificeres med et heltal, kaldet indeks. Med dette perspektiv kan et array implementeres på mange måder.

Datastrukturen array Realisering i Java: Oprettelse: int a[] = new int[100]; eller int[] a = new int[100]; opretter et array med 100 elementer af typen int: a[0], a[1], ..., a[99] Tilgang til et element: a[27] Aflæsning af arrayets længde: a.length (= 100)

Vigtig egenskab Tilgangstiden til ethvert element er konstant. 0: 1: 2: 3: 4: 5: 6: adresse(a[i]) = adresse(a[0]) + i*længde(type) adresse(a[0])

Eratosthenes si (Eratosthenes, cirka 300 f. Kr.) Problem: udskriv alle primtal ≤ N Et primtal er et positivt heltal ≥ 2, som ikke er deleligt med andre tal end 1 og sig selv, f.eks. 2, 3, 5, 7, 11. Ide til algoritme: Opret et boolean array isPrime med alle elementer sat til true. Gennemløb herefter alle tal mellem 2 og N, som er produktet af to tal (begge > 1), og sæt isPrime til false for disse. Herefter udskrives de tal, i, hvor isPrime[i] stadig er true. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50

Vanskeligheden ligger i gennemløbet. Vi skal gennemløbe alle tal i*j, hvor i ≥ 2, j ≥ 2 og i*j ≤ N. Hvis j ≥ 2 og i *j ≤ N, så må i ≤ N/2. Hvis i *j ≤ N, så må j ≤ N/i. Dette giver nedenstående Java-program. public class Eratosthenes { final static int N = 100000000; public static void main(String args[]) { boolean isPrime[] = new boolean[N+1]; int i, j; for (i = 2; i <= N; i++) isPrime[i] = true; for (i = 2; i <= N/2; i++) for (j = 2; j <= N/i; j++) IsPrime[i*j] = false; if (IsPrime[i]) IO.print(i + " "); IO.println(); } }

Effektivisering for (i = 2; i <= N/2; i++) for (j = 2; j <= N/i; j++) IsPrime[i*j] = false; Koden kan effektiviseres ved at indsætte testen if (isPrime[i]) før j-løkken. Hvorfor? I j -løkkens itialiseringsdel kan j = 2 erstattes med j = i. Hvorfor? I i-løkkens betingelsesdel kan i <= N/2 erstattes med i*i <= N. Hvorfor? for (i = 2; i*i <= N; i++) if (isPrime[i]) for (j = i; j <= N/i; j++) IsPrime[i*j] = false;

Måling af programeffektivitet Version 1: for (i = 2; i <= N/2; i++) for (j = 2; j <= N/i; j++) IsPrime[i*j] = false; Version 2: for (i = 2; i <= N/2; i++) if (isPrime[i]) for (j = 2; j <= N/i; j++) IsPrime[i*j] = false; Version 3: for (i = 2; i <= N/2; i++) if (isPrime[i]) for (j = i; j <= N/i; j++) IsPrime[i*j] = false; Version 4: for (i = 2; i*i <= N; i++) if (isPrime[i]) for (j = i; j <= N/i; j++) IsPrime[i*j] = false; Version 5: for (i = 2; i*i <= N; i++) if (isPrime[i]) for (p = i*i; p <= N; p += i) IsPrime[p] = false; Version j/p -iterationer Tid (sek) 1 1,657,511,569 491.0 2 309,275,826 74.2 3 242,570,204 48.2 4 242,570,204 44.7 5 242,570,204 44.7 N = 100,000,000 Mac G3, 233 MHz

Måling af tidsforbrug i Java double startTime = System.currentTimeMillis(); Kode IO.println("Time: " + (System.currentTimeMillis() - startTime)/1000 + "seconds");

2-dimensionale arrays Realisering i Java: Oprettelse: int a[][] = new int[5][4]; opretter et array med 5*4 = 20 heltallige elementer: a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] a[3][0] a[3][1] a[3][2] a[3][3] a[4][0] a[4][1] a[4][2] a[4][3] Tilgang til element: a[3][2] Aflæsning af antal rækker: a.length (= 5) Aflæsning af antal søjler: a[0].length (= 4)

Eksempel på anvendelse For en mængde elever er oplyst deres karakterer i en række fag. Programmér en metode i Java, der kan beregner karaktergennemsnittet for en given elev. int karakter[][] = new int[100][10]; // 100 elever, 10 fag float gennemsnit(int elev, int k[][]) { int sum = 0; for (int f = 0; f < k[elev].length; f++) sum += k[elev][f]; return ((float) sum)/k[elev].length; } Beregning af gennemsnittet for elev nummer 3: gennemsnit(3, karakter);

Kompakt repræsentation af symmetrisk matrix 1 n aij = aji for alle 1≤i≤n og 1≤j≤n public class TriangularMatrix { private int a[][]; public TriangularMatrix(int n) { a = new int[n][]; for (int i = 0; i < n; i++) a[i] = new int[i+1]; } public int get(int i, int j) { return i >= j ? a[i-1][j-1] : a[j-1][i-1]; } public void set(int i, int j, int value) { if (i >= j) a[i-1][j-1] = value; else a[j-1][i-1] = value; } }

Hægtede lister En hægtet liste er en mængde at dataelementer, der er organiseret sekventielt, således at hvert element (kaldet en knude) indeholder en peger (kaldet en hægte) til det næste element. A L I S T Bemærk: enhver knude indeholder en hægte, også listens sidste. I lærebogen benyttes konsekvent følgende konvention (head og z er ekstraknuder): A L I S T z head

Operationer på hægtede lister (1) Indsættelse X z A L I S T head Tidsforbrug: Konstant. Kun 2 hægter skal ændres (uafhængigt af listens længde) (2) Sletning A L I S T z head X Tidsforbrug: Konstant. Kun 1 hægte skal ændres (uafhængigt af listens længde)

Arrays og hægtede lister (pro et contra) • Visse operationer er mere effektive for en liste end for et array, f.eks. indsættelse og sletning. Men visse operationer er mere effektive for et array, f.eks. bestemmelse af det k´te element. • En array-repræsentation fylder mindre (der spares plads til hægterne).

Implementering af hægtede lister i Java class Node { Node next; } class ListItem extends Node { String key; // eller int key; ListItem(String k) { key = k; } z head Oprettelse af en tom liste: Node head = new Node(), z = new Node(); head.next = z.next = z;

Implementering af indsættelse og sletning class Node { Node next; public void insertAfter(Node t) { next = t.next; t.next = this; } public void deleteAfter(Node t) { t.next = next; t t.next this

Cirkulær hægtet liste (Josephus problem) Problem. N personer står i en rundkreds. Den M´te person i rundkredsen begår selvmord, indtil alle er døde. Hvem begår selvmord sidst? int N = IO.readInt(), M = IO.readInt(); Node t = new ListItem(1), x = t; for (int i = 2; i <= N; i++) t = t.next = new ListItem(i); t.next = x; while (t != t.next) { for (int i = 1; i < M; i++) t = t.next; x = t.next; t.next = x.next; } IO.println(((ListItem) t).key); t x next

Array repræsentation af lister Objektreferencer erstattes af indices. Enten ved class Node { int next; String key; } Node table[] = new Node[2+N]; int z = 0, head = 1; table[head].next = table[z].next = z; eller ved parallelle arrays: integer next[] = new int[2+N]; String key[] = new String[2+N]; int z = 0, head = 1; next[head] = next[z] = z;

Fri liste Flere lister kan være repræsenteret i et og samme array, bl.a. en liste over ubenyttede knuder, en såkaldt fri liste. int z = 0, head = 1, free; next[head] = next[z] = z; for (free = 2; free < N; free++) next[free] = free+1; next[N] = z; free = 2; Dermed kan programmøren selv håndtere automatisk lagerallokering: Allokering: (svarer til x = new ...) x = free; free = next[free]; Frigivelse: (af x) next[x] = free; free = x;

Dobbelthægtede lister Problemer med enkelthægtede lister: En knude kan ikke fjernes effektivt fra en liste, med mindre forgængerknuden er kendt. Listen kan kun gennemløbes i én retning. Løses med en dobbelthægtet liste. A L I S T I det følgende præsenteres en Java-pakke til håndtering af tovejslister. Pakken svarer helt til Simulas indbyggede pakke SIMSET.

Klasserne Link og Head fra en klients synspunkt first() last() suc() null pred() Head Link Head: Listehovedet Link: Et listeelement

Pakken simset package simset; public class Head { public Link first(); public Link last(); public boolean empty(); public int cardinal(); public void clear(); } public class Link { public Link pred(); public Link suc(); public void out(); public void into(Head h); public void follow(Link_eller_Head p); public void precede(Link_eller_Head p); }

Eksempel på anvendelse (oprettelse og udskrivning af en liste af tal) import simset.*; import IO.*; class Number extends Link { int value; Number(int v) { value = v; } } Head list = new Head(); for (int i = 1; i <= 10; i++) new Number(i).into(list); Number n = (Number) list.first(); while (n != null) { IO.println(n.value); n = (Number) n.suc(); } while (!list.empty()) { n = (Number) list.first(); n.out();

Skabeloner for listegennemløb (1) e = list.first(); while (e != null) { process(e); e = e.suc(); } eller: (2) for (e = list.first(); e != null; e = e.suc()) process(e);

Implementationen af klasserne i simset SUC PRED Head extends Linkage Link

Class Linkage (fælles overklasse for Head og Link) public class Linkage { public Link pred() { return PRED instanceof Link ? (Link) PRED : null; } public Link suc() { return SUC instanceof Link ? (Link) SUC : null; } public Linkage prev() { return PRED; } Linkage PRED, SUC; }

class Head public class Head extends Linkage { public Head() { PRED = SUC = this; } public Link first() { return suc(); } public Link last() { return pred(); } public boolean empty() { return SUC == this; } public int cardinal() { int i = 0; Link p; for (p = first(); p != null; p = p.suc()) i++; return i; } public void clear() { while (first() != null) first().out(); }

class Link public class Link extends Linkage { public void out() { if (SUC != null) { SUC.PRED = PRED; PRED.SUC = SUC; SUC = PRED = null; } public void follow(Linkage p) { out(); if (p != null && p.SUC != null) { PRED = p; SUC = p.SUC; SUC.PRED = p.SUC = this; public void precede(Linkage p) { SUC = p; PRED = p.PRED; PRED.SUC = p.PRED = this; public void into(Head h) { precede(h); }

Metoden out SUC PRED public void out() { if (SUC != null) { SUC.PRED = PRED; PRED.SUC = SUC; SUC = PRED = null; } SUC PRED this

Metoden follow SUC PRED public void follow(Linkage p) { out(); if (p != null && p.SUC != null) { PRED = p; SUC = p.SUC; SUC.PRED = p.SUC = this; } SUC PRED this p

En stak (LIFO = LastInFirstOut) En stak er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: push(v): Læg dataelementet v øverst på stakken (dvs. i begyndelsen af stakken) pop: Fjern det øverste element på stakken Stak pop push

En stak er en abstrakt datatype public class Stack { public Stack(int max); public Stack(); public void push(ItemType v); public ItemType pop(); public boolean empty(); } Itemtype skal erstattes af en type, f.eks. char eller Object.

Repræsentation af stak ved hjælp af array public class Stack { private char stack[]; private int p; public Stack(int max) { stack = new char[max]; p = 0; } public Stack() { this(100); } public void push(char v) { stack[p++] = v; } public char pop() { return stack[--p]; } public boolean empty() { return p == 0; } } Itemtype er her char. Kan noget gå galt?

Repræsentation af stak ved hjælp af hægtet liste class Node { char key; Node next; } public class Stack { private Node head, z; public Stack() { head = new Node(); z = new Node(); head.next = z; z.next = head; } public Stack(int max) { this(); } public void push(char v) { Node t = new Node(); t.key = v; t.next = head.next; head.next = t; public char pop() { Node t = head.next; head.next = t.next; return t.key; public boolean empty() { return head.next == z; }

Anvendelse af stakke Beregning af aritmetiske udtryk Udførelse af metodekald

Eksempel på stakanvendelse (evaluering af postfix-udtryk) Infix-notation: Operatorer imellem operander, f.eks. a + b Postfix-notation (omvendt polsk): Operatorer efter operander, f.eks. a b + Fra infix til postfix: (a + b) -> a b + x + y * z -> x y z * + x + y - z -> x y + z - OBS: postfix-notation er parentesfri!

Evaluering af postfix-udtryk infix: ( 5 * ( ( ( 9 + 8 ) * ( 4 * 6 ) ) + 7 ) ) postfix: 5 9 8 + 4 6 * * 7 + * p p 5 p 5 9 p 5 9 8 p 5 17 p 5 17 4 p 5 4 17 6 p 5 17 24 p 5 408 p 5 408 7 p 5 415 p 2075

Et Java-program til evaluering af postfix-udtryk public class Program { static char get() throws IOException { return (char) System.in.read(); } public static void main(String[] args) throws IOException { char c; Stack acc = new Stack(50); while ((c = get()) != (char) (-1)) { while (c == ' ') c = get(); int x = 0; if (c == '+') x = acc.pop() + acc.pop(); if (c == '*') x = acc.pop() * acc.pop(); while (c >= '0' && c <= '9') { x = 10*x + (c-'0'); c = get(); } acc.push(x); } System.out.println(acc.pop());

Konvertering af infix-udtryk til postfix-udtryk (Dijkstras vigesporsalgoritme) Infix-streng Postfix-streng operander operatorer Operatorstak

Konvertering af infixudtryk, der er “mættet” med parenteser. 5 p 5 p * 5 9 p * 5 9 p * + 5 9 8 + 4 * p 5 9 8 p * + p * 5 9 8 + p * 5 9 8 + 5 9 8 + 4 6 * p p 5 9 8 + 4 6 * * * 5 9 8 + 4 6 * * p * + 5 9 8 + 4 6 * * 7 p + *

Et Java-program til konvertering af infix-udtryk til postfix-udtryk public class Program { static char get() throws IOException { return (char) System.in.read(); } static void put(char c) { System.out.print(c); } public static void main(String[] args) throws IOException { char c; Stack save = new Stack(50); while ((c = get()) != (char) (-1)) { if (c == ')') put(save.pop()); if (c == '+' || c == '*') save.push(c); while (c >= '0' && c <= '9') { put(c); c = get(); } if (c != '(') put(' '); } put('\n');

Brug af stak til håndtering af metodekald int f(int a1, int a2, int a3) { int b1, b2, b3; } } f ' s returværdi o r i g e a k t v n s p u d 1 2 3 b S l B Aktiveringspost

En kø (FIFO = FirstInFirstOut) En kø er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: put(v): Sæt dataelementet v bagest i køen get: Fjern det første element fra køen get put Kø

Repræsentation af kø ved hjælp af array (cirkulær buffer) head tail v2 v3 v4 v5 head tail get v2 v3 v4 v5 head tail put(v6) v6

Hvad er betingelsen for at køen er fuld? Svar: (tail+1)%size == head public class Queue { private char queue[]; private int head, tail, size; public Queue(int max) { size = max; queue = new char[max + 1]; head = tail = 0; } public Queue() { this(100); } public void put(char v) { queue[tail++] = v; if (tail > size) tail = 0; public char get() { char t = queue[head++]; if (head > size) head = 0; return t; public boolean empty() { return head == tail; } Hvad er betingelsen for at køen er fuld? Svar: (tail+1)%size == head

Implementation af kø ved hjælp af pakken simset import simset.*; class Node extends Link { char key; Node(char key) { this.key = key; } } public class Queue { private Head q; public Queue() { q = new Head(); } public void put(char v) { new Node(v).into(q); } public char get() { Node t = (Node) q.first(); t.out(); return t.key; public boolean empty() { return q.empty(); }

Java-klassen Vector (en klasse til håndtering af dynamiske tabeller) class Vector { Object elementAt(int index); void setElementAt(Object obj, int index); void insertElementAt(Object obj, int index); void removeElementAt(int index); void addElement(Object obj); void removeElement(Object obj); boolean contains(Object obj); boolean isEmpty(); int size(); int indexOf(Object obj); Object firstElement(); Object lastElement(); }

Java-klassen Stack (implementeret ved hjælp af class Vector) class Stack extends Vector { Object push(Object obj) { addElement(obj); return obj; } Object pop() { Object obj = peek(); removeElementAt(size() - 1); Object peek() { int len = size(); if (len == 0) throw new EmptyStackException(); return elementAt(len - 1); public boolean empty() { return size() == 0; }

Træer Et træ er en samling af knuder og kanter, (V, E), som opfylder visse krav: En knude, v, er et simpelt dataobjekt, der kan have et navn og en tilknyttet information. En af knuderne er udpeget som rod i træet. En kant, (v1,v2), er en forbindelse imellem to knuder, v1 og v2. En vej er en liste af knuder, (v1,v2, ... ,vk), hvor alle successive knuder, vi og vi+1, er indbyrdes forbundne (dvs. tilhører E). For at udgøre et træ skal der mellem roden og enhver anden knude findes præcis én vej.

Terminologi Rod: R X er far til Y Y er søn til X Y er barn af X Z T U V W Terminal (blad) Ikke-terminal Niveau 0 Niveau 1 Niveau 2 Niveau 3 Rod: R X er far til Y Y er søn til X Y er barn af X U, V og W er børn af T S er bedstefar til Z S er forgænger til Y S er over Y Y er efterkommer af S Y er under S Terminale knuder (blade): Y, Z, U, V, W Ikke-terminale knuder: R, S, X, T

Terminologi (fortsat) En knudes niveau er antallet af knuder på vejen fra knuden til roden (minus knuden selv). Et træs højde er det maksimale niveau for alle knuder i træet.

Terminologi (fortsat) Enhver knude i et træ er rod for et undertræ bestående af knuden selv og alle knuder under den. Et træ kaldes ordnet, hvis rækkefølgen af sønnerne for enhver knude er specificeret. En mængde af træer kaldes en skov.

Egenskaber ved træer For enhver knude i et træ er der præcis én vej, der fører fra roden til knuden. Et træ er sammenhængende, dvs. der er en vej fra enhver knude til enhver anden knude. Et træ har ingen cykler, dvs. enhver vej indeholder en knude højst én gang. Nyttig definition: Et tomt træ er et træ uden kanter og knuder.

Anvendelser af træer Repræsentation af hierarkier indholdsfortegnelse organisationsstruktur klassehierarki blokstruktur Søgning Sortering Syntaksanalyse

Binære træer Et flervejstræ er et træ, hvor hver knude har et bestemt antal sønner (eller ingen). I et flervejstræ er det ofte hensigtsmæssigt at definere specielle eksterne knuder, der ikke har nogen sønner og ikke har tilknyttet nogen information (dummy-knuder). Et binært træ er et ordnet træ bestående af to typer af knuder: interne knuder med præcis to sønner, og eksterne knuder, der er uden sønner. Rekursiv definition: Et binært træ er enten et tomt træ, eller en knude, som har et venstre og et højre binært undertræ.

Eksempel på binært træ P M L E S R A T P’s venstre søn er M P’s højre søn er L

Fulde binære træer Et fuldt binært træ er et binært træ, hvor de interne knuder fuldstændigt udfylder ethvert niveau, eventuelt med undtagelse af det sidste. Højden af et fuldt binært træ med N knuder er cirka log2N. Faktisk lig med | log2N |. Udtrykt i Java: Math.ceil(log(N)/log(2))

Komplette binære træer Et komplet binært træ er et fuldt binært træ, hvor de interne knuder på det sidste niveau er til venstre for alle de eksterne knuder på dette niveau. Alternativ definition: Et komplet binært træ er et binært træ med blade på kun et eller to successive niveauer, og bladene på det nederste niveau er placeret så langt til venstre som muligt.

Repræsentation af binære træer class Node { Node l, r; char info; } Eksempel på anvendelse: konstruktion af parsetræer. * A + F E D B C Parsetræ for udtrykket A * ( ( ( B + C ) * ( D * E ) ) + F) postfix: A B C + D E * * F + *

Java-kode til opbygning af et parsetræ ud fra et postfix-udtryk Et parsetræ konstrueres ved følgende rekursive regel: Læg operatoren i roden. Lad rodens venstre undertræ være parsetræet for den del af udtrykket, der svarer til venstre operand, og lad rodens højre undertræ være parsetræet for den del af udtrykket, der svarer til højre operand. Node z = new Node(); z.l = z.r = z; Stack stack = new Stack(50); char c; while ((c = get()) != (char) (-1)) { while (c == ' ') c = get(); Node x = new Node(); x.info = c; x.l = z; x.r = z; if (c == '+' || c == '*') { x.r = stack.pop(); x.l = stack.pop(); } stack.push(x);

* A + * F + * B C D E while ((c = get()) != (char) (-1)) { while (c == ' ') c = get(); Node x = new Node(); x.info = c; x.l = z; x.r = z; if (c == '+' || c == '*') { x.r = stack.pop(); x.l = stack.pop(); } stack.push(x); A B C + D E * * F + * * A + * F + * B C D E

Gennemgang af binære træer (traversering: besøg alle knuder i et træ) (1) Preorder (far-først): Besøg roden. Besøg venstre undertræ. Besøg højre undertræ. P M S A L E R T P M S A A L E R T E E (2) Inorder (symmetrisk): Besøg venstre undertræ. Besøg roden. Besøg højre undertræ. A S A M P L E T R E E (3) Postorder (far-sidst): Besøg venstre undertræ. Besøg højre undertræ. Besøg roden. A A S M T E E R E L P

Preorder-traversering ved hjælp af eksplicit stak void traverse(Node t) { stack.push(t); while (!stack.empty()) { t = stack.pop(); visit(t); if (t.r != z) stack.push(t.r); if (t.l != z) stack.push(t.l); } Stakken bruges til at udsætte et “besøg” til en senere lejlighed.

Traversering i niveauorden P M S A L E R T (4) Niveauorden: Besøg knuderne efter stigende niveau, og fra venstre mod højre på hvert niveau. P M L S E A A R T E E void traverse(Node t) { queue.put(t); while (!queue.empty()) { t = queue.get(); visit(t); if (t.l != z) queue.put(t.l); if (t.r != z) queue.put(t.r); }

Repræsentation af flervejstræer (1) Far-referencer class Node { Node dad; } (2) Binært træ class Node { Node firstSon, nextBrother; }

Ugeseddel 2 23. september - 29. september • Læs kapitel 5, 6 og 7 i lærebogen (side 51-87) • Løs følgende opgaver 1. Opgave 3.2 og 3.3 (idet “struct node *t” i begge opgaver erstattes med “node t”). 2. Opgave 3.5. 3. Opgave 4.1 og 4.3. 4. Java indeholder en klasse, class Stack, der kan benyttes til at repræsentere en stak af objekter. Klassen er implementeret ved hjælp af Java-klassen Vector. Derimod findes der i Javas klassebiblioteker ingen klasse til repræsentation af køer. (a) Implementer ved hjælp af class Vector en klasse, Queue, til repræsentation af køer. (b) Angiv hvilke af de implementerede metoder i Queue, der er konstant i tid, og hvilke der har en udførelsestid, der afhænger af den aktuelle kølængde. Se her bort fra eventuelt tidsforbrug til ekspansion af den anvendte vektor.

Reasoning About Programs E. W. Dijkstra Video vises i biografen torsdag den 30. september Start: 1445 Varighed: cirka 40 minutter