Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Fundamentale datastrukturer

Lignende præsentationer


Præsentationer af emnet: "Fundamentale datastrukturer"— Præsentationens transcript:

1 Fundamentale datastrukturer

2 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

3 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”.

4 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.

5 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

6 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

7 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.

8 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)

9 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])

10 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

11 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 = ; 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(); } }

12 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;

13 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) ,657,511, ,275, ,570, ,570, ,570, N = 100,000,000 Mac G3, 233 MHz

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

15 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)

16 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);

17 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; } }

18 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

19 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)

20 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).

21 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;

22 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

23 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

24 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;

25 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;

26 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.

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

28 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); }

29 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();

30 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);

31 Implementationen af klasserne i simset
SUC PRED Head extends Linkage Link

32 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; }

33 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(); }

34 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); }

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

36 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

37 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

38 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.

39 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?

40 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; }

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

42 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!

43 Evaluering af postfix-udtryk
infix: ( 5 * ( ( ( ) * ( 4 * 6 ) ) + 7 ) ) postfix: * * 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

44 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());

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

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

47 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');

48 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

49 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

50 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

51 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

52 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(); }

53 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(); }

54 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; }

55 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.

56 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

57 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.

58 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.

59 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.

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

61 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æ.

62 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

63 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))

64 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.

65 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 + *

66 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);

67 * 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

68 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

69 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.

70 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); }

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

72 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.

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


Download ppt "Fundamentale datastrukturer"

Lignende præsentationer


Annoncer fra Google