Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer,

Lignende præsentationer


Præsentationer af emnet: "1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer,"— Præsentationens transcript:

1 1 Fundamentale datastrukturer

2 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer, hægtede lister, træer, hashtabeller, prioritetskøer Collections Plan

3 3 Definitioner En type er en samling af værdier. Eks. int betegner i Java den type, der udgøres af heltallene fra -2147483648 til 2147483647. En abstrakt datatype er en datatype, der udelukkende er specificeret ved hjælp af typen og de tilknyttede operationer. En datatype er en type tilknyttet en mængde af operationer på typen. Eks. int er en datatype. Addition er et eksempel på en tilknyttet operation. Kun operationernes input/output-relationer er specificeret - ikke deres konkrete realisering. Hverken datarepræsentation eller algoritmer må medtages i specifikationen. En abstrakt datatype (ADT) specificerer “hvad”, men ikke “hvordan”.

4 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. Specificeres ofte ved hjælp af en grænseflade.

5 5 En datastruktur er en samling variable, muligvis af forskellig type, der er indbyrdes forbundet. Realisering i Java: ved simple variable, arrays og objekter Datastrukturer

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

7 7 (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 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 9 Vigtig egenskab Tilgangstiden til ethvert element er konstant. a[0] a[1] a[2] a[3] a[4] a[5] a[6] 0: 1: 2: 3: 4: 5: 6: adresse( a[i] ) = adresse( a[0] ) + i *længde(type) adresse( a[0] )

10 10 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] 2-dimensionale arrays Tilgang til et element: a[3][2] Aflæsning af antal rækker: a.length (= 5) Aflæsning af antal søjler: f.eks. a[0].length (= 4)

11 11 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. Hægtede lister Bemærk: enhver knude indeholder en hægte, også listens sidste. ALI S T first

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

13 13 Implementering af hægtede lister i Java ListNode Object ListNode Object class ListNode { ListNode next; Object element; }

14 14 class ListNode { ListNode next; Object element; void insertAfter(ListNode t) { next = t.next; t.next = this; } void deleteAfter(ListNode t) { t.next = next; } } Implementering af indsættelse og sletning t t.next this

15 15 Gennemløb af hægtet liste (idiom) ListNode current = firstNode; while (current != null) { process(current.element); current = current.next; } for (ListNode current = firstNode; current != null; current = current.next) process(current.element); eller

16 16 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. ListNode Object ListNode Object class ListNode { ListNode prev, next; Object element; }

17 17 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 (flytning undgås). Men visse operationer er mere effektive for et array, f.eks. bestemmelse af det i´te element. En array-repræsentation fylder mindre (der spares plads til hægterne).

18 18 En stak (LIFO = LastInFirstOut) En stak er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: push(x): Læg dataelementet x øverst på stakken pop: Fjern det øverste element på stakken Stak poppush Kun stakkens øverste element ( top ) er tilgængeligt

19 19 En stak er en abstrakt datatype public interface Stack { void push(Object x); void pop(); Object top(); Object topAndPop(); boolean isEmpty(); }

20 20 Et simpelt testprogram public class TestStack { public static void main(String[] args) { Stack s = new ArrayStack(); for(int i = 0; i < 5; i++) s.push(new Integer(i)); while (!s.isEmpty()) System.out.print(s.topAndPop() + " "); }

21 21 Anvendelser af en stak En stak kan bl.a. bruges til at vende om på en given rækkefølge (at gøre noget baglæns) at gemme mellemresultater f.eks. ved beregning af udtrykket 3*4 + 5*6 +7 at behandle parentetiske strukturer f.eks. ved kontrol af, om parenteserne stemmer i sekvensen { [ ( { } ( ) ] ) }

22 22 En kø (FIFO = FirstInFirstOut) En kø er en sekvens af dataelementer af samme type, som muliggør følgende to operationer: enqueue(x): Sæt dataelementet x bagest i køen dequeue: Fjern det forreste element fra køen dequeue enqueue Kø

23 23 En kø er en abstrakt datatype public interface Queue { void enqueue(Object x); Object dequeue(); Object getFront(); boolean isEmpty(); }

24 24 Et simpelt testprogram public class TestQueue { public static void main(String[] args) { Queue q = new ArrayQueue(); for(int i = 0; i < 5; i++) q.enqueue(new Integer(i)); while (!q.isEmpty()) System.out.print(q.dequeue() + " "); }

25 25 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, (v 1,v 2 ), er en forbindelse imellem to knuder, v 1 og v 2. En vej er en liste af knuder, (v 1,v 2,...,v k ), hvor alle successive knuder, v i og v i+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. Træer

26 26 Terminologi Rod: R Blade: Y, Z, U, V, W Indre knuder : R, S, T, X Rod R S X YZ T U V W Blad Indre knude 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)

27 27 Eksempel på anvendelse af træer (et filsystem ) Et filsystem kan beskrives ved et træ: Knuderne repræsenterer kataloger og filer. Træets blade indeholder filer (eller tomme kataloger). Andre eksempler: stamtræ, indholdsfortegnelse, organisationsstruktur

28 28 Terminologi (fortsat) Et tomt træ er et træ uden kanter og knuder. 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.

29 29 Binære træer 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æ. Et binært træ er et ordnet træ, hvor hver knude har højst 2 sønner.

30 30 Eksempel på binært træ N er P’s venstre søn L er P’s højre søn P N S A B L E R X V T

31 31 class BinaryNode { BinaryNode left, right; Object element; } Repræsentation af binære træer En null -reference angiver et tomt (under)træ

32 32 * A + F * * E D + BC Træ for udtrykket A * ( ( ( B + C ) * ( D * E ) ) + F) Eksempel på anvendelse af binære træer (et udtrykstræ ) operator (i indre knude) operand (i blad)

33 33 Binære søgetræer (muliggør søgning i logaritmisk tid) I E A B F H L N R X G M S P Et binært søgetræ, er et binært træ, hvor der for hver knude gælder, at alle knuder i dets venstre undertræ er mindre end knuden, og alle knuder i dets højre undertræ er større end knuden.

34 34 Binære søgetræer public interface BinarySearchTree { void insert(Comparable x); Comparable find(Comparable x); Comparable findMin(); Comparable findMax(); void remove(Comparable x); void removeMin(); void removeMax(); boolean isEmpty(); }

35 35 Hashtabeller (muliggør søgning i konstant tid) public interface HashTable { void put(Object key, Object value); Object get(Object key); boolean containsKey(Object key); boolean isEmpty(); }

36 36 Et simpelt testprogram public class TestHashTable { public static void main(String[] args) { HashTable h = new QuadraticProbingTable(); h.put("Hansen", "351348"); h.put("Jensen", "421927"); Object result = h.get("Hansen"); if (result != null) System.out.println("Found " + result); else System.out.println("Hansen not found"); }

37 37 Prioritetskøer (muliggør behandling af elementer i prioriteret rækkefølge) public interface PriorityQueue { Position insert(Comparable x); Comparable findMin(); Comparable deleteMin(); boolean isEmpty(); void decreaseKey(Position p, Comparable newVal); public interface Position { Comparable getValue();} }

38 38 Et simpelt testprogram public class TestPriorityQueue { public static void main(String[] args) { PriorityQueue pq = new BinaryHeap(); pq.insert(new Integer(4)); pq.insert(new Integer(2)); pq.insert(new Integer(1)); pq.insert(new Integer(3)); pq.insert(new Integer(0)); while (!pq.isEmpty()) System.out.print(pq.deleteMin() + " "); }

39 39 DatastrukturTilgang StakKun det nyeste element, pop : O(1) KøKun det ældste element, dequeue : O(1) Hægtet listeEthvert element, O(N) SøgetræEthvert element, O(log N) HashtabelEthvert element, O(1) Prioritetskø findMin : O(1), deleteMin : O(log N) Sammenfatning af datastrukturerne

40 40 Collections

41 41 En kollektion er en samling af objekter. Javas collections er et sæt af grænseflader og klasser, der understøtter lagring og genfinding af objekter i kollektioner. Kollektionerne kan være baseret på forskellige datastrukturer og algoritmer (og dermed have forskellige tids- og pladskompleksitet). Kollektioner En kollektion er et objekt, der fungerer som en beholder for andre objekter. Disse kaldes for kollektionens elementer.

42 42 Abstrakte kollektioner En mængde (Set) er en uordnet kollektion, som ikke må indeholde dubletter. En liste (List) er en ordnet kollektion, som gerne må indeholde dubletter. Ethvert element har en position. En afbildning (Map) er en uordnet kollektion af nøgle- værdi-par. Nøglerne skal være unikke.

43 43 Map SortedMap Collection SortedSet SetList Grænseflader for kollektioner java.util.*

44 44 Konkrete kollektioner HashSet implements Set : O(1) TreeSet implements SortedSet : O(log N) ArrayList implements List LinkedList implements List HashMap implements Map TreeMap implements SortedMap Vector implements List JDK 1.0 Hashtable implements Map

45 45 boolean add(Object o) boolean addAll(Collection c) void clear() boolean contains(Object o) boolean containsAll(Collection c) boolean isEmpty() Iterator iterator() boolean remove(Object o) boolean removeAll(Collection c) boolean retainAll(Collection c) int size() interface Collection For primitive typer benyttes svøbeklasser

46 46 interface Set extends Collection boolean add(Object o) boolean addAll(Collection c) Ingen nye metoder, men kontrakterne for er ændret, således at et objekt kun tilføjes, hvis der ikke findes en dublet (dette afgøres med equals ).

47 47 Eksempel på anvendelse af Set Set set = new HashSet(); set.add("cat");set.add("dog"); int n = set.size(); System.out.println("The set contains " + n + " elements"); if (set.contains("dog")) System.out.println("dog is in the set");

48 48 interface List extends Collection void add(int i, Object o) Object get(int i) int indexOf(Object o) int lastIndexOf(Object o) ListIterator listIterator() ListIterator listIterator(int i) Object remove(int i) Object set(int i, Object o) List subList(int i, int j) Nye metoder: Ændrede kontrakter for add(o), addAll(c) og remove(o).

49 49 interface Map Object put(Object k, Object v) Object get(Object k) Object remove(Object k) void clear() boolean containsKey(Object k) boolean containsValue(Object v) Set entrySet() boolean isEmpty() Set keySet() void putAll(Map m) int size() Collection values()

50 50 Eksempel på anvendelse af Map Map map = new HashMap(); map.put("cat", "kat");map.put("dog", "hund"); Object val = map.get("dog"); // val is "hund" map.remove("cat"); map.put("dog", "køter"); val = map.get("dog"); // val is "køter" (indholdsadresserbar tabel)

51 51 Valg af konkret kollektion for en mængde Hvis elementerne skal kunne gennemløbes i en bestemt rækkefølge, benyttes TreeSet ; ellers HashSet. Forudsætninger: Klassen af elementer skal implementere metoden equals. Hvis TreeSet benyttes, skal klassen af elementer implementere grænsefladen Comparable ; eller TreeSet skal instantieres med et Comparator -objekt. Hvis HashSet benyttes, skal klassen af elementer implementere metoden hashCode.

52 52 Om brug af hashCode Tænk på værdien af hashCode som et vink om, på hvilken plads i tabellen, objektet ligger. int hashCode() Der bør for ethvert par af objekter ( o1, o2 ) gælde: o1.equals(o2)  o1.hashCode() == o2.hashCode() Ideelt set (men ofte ikke praktisk muligt) desuden: !o1.equals(o2)  o1.hashCode() != o2.hashCode()

53 53 Valg af konkret kollektion for en liste Hvis opslag på indices er hyppig, og hvis længden af listen kun varierer lidt, benyttes ArrayList ; ellers LinkedList.

54 54 Valg af konkret kollektion for en afbildning Hvis nøglerne skal kunne gennemløbes i en bestemt rækkefølge, benyttes TreeMap ; ellers HashMap. Forudsætninger: Klasserne af nøgler og værdier skal implementere metoden equals. Hvis HashMap benyttes, skal klassen af nøgler implementere metoden hashCode. Hvis TreeMap benyttes, skal klassen af nøgler implementere grænsefladen Comparable, eller TreeMap skal instantieres med et Comparator -objekt.

55 55 Ved at tilgå en datastrukturs elementer igennem en iterator opnås: (1) dataabstraktion (2) sikkerhed mod forkert brug Den underliggende repræsentation afsløres ikke. Iterator - et designmønster -

56 56 Gennemløb af kollektioner Til gennemløb af kollektioner er defineret to grænseflader: interface Iterator { boolean hasNext(); Object next(); void remove(); } interface ListIterator extends Iterator { boolean hasPrevious(); Object previous(); void add(Object o); int previousIndex(); int nextIndex(); void set(Object o); }

57 57 Eksempel på brug af Iterator List list = new ArrayList(); list.add("Arne");... list.add("Kurt"); Iterator itr = list.iterator(); while (itr.hasNext()) System.out.println(itr.next());

58 58 Konkret iterator for ArrayList int size = 3 Object[] items ArrayList private int current = 0 ArrayList myList ArrayListIterator private

59 59 Implementering class ArrayListIterator implements Iterator { int current = 0; ArrayList myArrayList; ArrayListIterator(ArrayList a) { myArrayList = a; } public boolean hasNext() { return current < myArrayList.size(); } public Object next() { return myArrayList.items[current++]; }

60 60 Konkrete iteratorer En konkret iterator fås ved kald af iterator() fra grænsefladen Collection, eller ved kald af listIterator() fra grænsefladen List. Gennemløb af en afbildning (3 syn): Syn Kald Type nøgler keySet().iterator() Klassen af nøgler værdier values().iterator() Klassen af værdier indgange entrySet().iterator() Map.Entry

61 61 Ordning og sortering Der er to måder at definere orden imellem objekter: (1)Ved at implementere grænsefladen Comparable for klassen af objekter (naturlig orden). (2) Ved at anvende et objekt fra en klasse, der implementerer grænsefladen Comparator.

62 62 Grænsefladen Comparable interface Comparable { int compareTo(Object o); } Kontrakt for metoden compareTo : Returner et heltal < 0,hvis this kommer før o. Returner 0, hvis this hverken kommer før eller efter o. Returner et heltal > 0,hvis this kommer efter o. Mange af klasserne i JDK, implementerer Comparable, bl.a. String.

63 63 Grænsefladen Comparator interface Comparator { int compare(Object o1, Object o2); } Kontrakt for metoden compare : Returner et heltal < 0,hvis o1 kommer før o2. Returner 0, hvis o1 hverken kommer før eller efter o2. Returner et heltal > 0,hvis o1 kommer efter o2.

64 64 interface SortedSet extends Set Object first() Object last() SortedSet headSet(Object o) // < o SortedSet tailSet(Object o) // ≥ o SortedSet subSet(o1, o2) Comparator comparator() En konkret implementering, f.eks. TreeSet, tilbyder mindst to konstruktører: en uden parametre, og en med en Comparator som parameter

65 65 interface SortedMap extends Map Object firstKey() Object lastKey() SortedMap headMap(Object o) // < o SortedMap tailMap(Object o) // ≥ o SortedMap subMap(o1, o2) Comparator comparator() En konkret implementering, f.eks. TreeMap, tilbyder mindst to konstruktører: en uden parametre, og en med en Comparator som parameter

66 66 Klassen Collections public class Collections { public static void sort(List l);public static void sort(List l, Comparator comp); public static int binarySearch(List l, Object k);public static int binarySearch(List l, Object k, Comparator comp); public static Object min(Collection c);public static Object min(Collection c, Comparator c);public static Object max(Collection c);public static Object max(Collection c, Comparator c); }

67 67 Opgave: Skriv et program, der indlæser en tekst og bestemmer det totale antal ord samt antallet af forskellige ord i teksten.

68 68 public class CountWords {static public void main(String[] args) { HashSet words = new HashSet(); BufferedReader in = new BufferedReader( new InputStreamReader(System.in)); String line; int count = 0; try { while ((line = in.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { count++; words.add(st.nextToken().toLowerCase()); } } } catch (IOException e) {} System.out.println("Total number of words: " + count); System.out.println("Number of different words: " + words.size());} } Optælling af ord

69 69 Optælling af ordforekomster public class WordFrequency { static class Count { Count(int value) { this.value = value; } int value; } static public void main(String[] args) {... } } fortsættes

70 70 static public void main(String[] args) {Map words = new HashMap(); try { BufferedReader in = new BufferedReader( new FileReader(args[0])); String line; while ((line = in.readLine()) != null) { StringTokenizer st = new StringTokenizer(line); while (st.hasMoreTokens()) { String word = st.nextToken().toLowerCase(); Count count = (Count) words.get(word); if (count == null) words.put(word, new Count(1)); else count.value++; } } in.close(); } catch (IOException e) {} //... print the word counts } fortsættes

71 71 Iterator itr = words.entrySet().iterator(); while (itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); String word = (String) entry.getKey(); Count count = (Count) entry.getValue(); System.out.println(word + ": " + count.value); }

72 72 Udskrivning efter ordenes alfabetiske rækkefølge Eneste ændring er, at Map words = new HashMap(); erstattes med Map words = new TreeMap();

73 73 Udskrivning i omvendt alfabetisk rækkefølge og sætningen TreeMap words = new TreeMap(); erstattes med TreeMap words = new TreeMap(new StringComparator()); Følgende klasse erklæres public class StringComparator implements Comparator { public int compare(Object o1, Object o2) { String s1 = (String) o1, s2 = (String) o2; return -(s1.compareTo(s2)); }

74 74 Udskrivning i frekvensrækkefølge Følgende klasse erklæres public class CountComparator implements Comparator { public int compare(Object o1, Object o2) { Count c1 = (Count) ((Map.Entry) o1).getValue(); Count c2 = (Count) ((Map.Entry) o2).getValue(); return c2.value - c1.value; } og... fortsættes

75 75 List list = new ArrayList(words.entries()); Collections.sort(list, new CountComparator()); Iterator itr = list.iterator(); while (itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); String word = (String) entry.getKey(); Count count = (Count) entry.getValue(); System.out.println(word + ": " + count.value);} udskrivningen foretages således:

76 76 Ugeseddel 4 9. oktober - 16. oktober Læs kapitel 7 Afsnit 7.4 kan læses kursorisk. Beviser kan overspringes. Løs følgende opgaver fra lærebogen Opgave 12: 6.8 (1 point) Opgave 13: 6.9 (1 point) Opgave 14: 6.12 (2 point, ikke-obligatorisk) Opgave 15: 6.13 (2 point, ikke-obligatorisk) Afleveringsfrist: tirsdag den 23. oktober


Download ppt "1 Fundamentale datastrukturer. 2 Definitioner: abstrakt datatype, datastruktur Elementære datastrukturer og abstrakte datatyper: arrays, stakke, køer,"

Lignende præsentationer


Annoncer fra Google