Ordnung im Materiallager: Datenstrukturen II. Suchen und Sortieren im Array Verkettete Listen Rekursion

Ähnliche Dokumente
Ordnung im Materiallager: Datenstrukturen

Programmieren 2 15 Abstrakte Datentypen

Faulheit professionell: Fertige Datenbehälter. Das Java-Collections-Framework Typsicherheit Generische Klassen

Programmieren 1 14 Pannnen, Pech und Pleiten: EXCEPTIONS

Einführung in die Objektorientierte Programmierung Vorlesung 18: Lineare Datenstrukturen. Sebastian Küpper

Programmieren 2 16 Java Collections und Generizität

16. Dynamische Datenstrukturen

Schnittstellen, Stack und Queue

13. Dynamische Datenstrukturen

ALP II Dynamische Datenmengen Datenabstraktion

Übung Algorithmen und Datenstrukturen

Fallstudie: Online-Statistik

Algorithmen und Programmierung III

7. Verkettete Strukturen: Listen

Schwerpunkte. Verkettete Listen. Verkettete Listen: 7. Verkettete Strukturen: Listen. Überblick und Grundprinzip. Vergleich: Arrays verkettete Listen

Nachtrag: Vergleich der Implementierungen von Stack

Problem: Was ist, wenn der Stapel voll ist? Idee: Erzeuge dynamisch ein grösseres Array und kopiere um. Dynamische Anpassung der Größe

ALP II Dynamische Datenmengen Datenabstraktion (Teil 2)

Einführung in die Programmierung

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

Software Entwicklung 1

Stacks, Queues & Bags. Datenstrukturen. Pushdown/Popup Stack. Ferd van Odenhoven. 19. September 2012

Programmieren 2 Übung Semesterwoche 2

12.3 Ein Datenmodell für Listen

Lösungen zum Übungsblatt 10: Entwicklung von Softwaresystemen I (WS 2003/04)

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Listen. Prof. Dr. Christian Böhm. in Zusammenarbeit mit Gefei Zhang. WS 07/08

Konkatenation zweier Listen mit concat

Software Entwicklung 1

5.3 Doppelt verkettete Listen

Aufgaben NF 11; Seite 1

Software Entwicklung 1

II.4.4 Exceptions - 1 -

Programmieren I. Kapitel 13. Listen

Teil IV. Grundlegende Datenstrukturen

Lineare Datenstrukturen: Felder, Vektoren, Listen Modelle: math. Folge (a i ) i=1.. mit Basistyp T oder: [T]

Übung Algorithmen und Datenstrukturen

1 Abstrakte Datentypen

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Spezielle Datenstrukturen

6. Verkettete Strukturen: Listen

Informatik II Prüfungsvorbereitungskurs

OCP Java SE 8. Collections

Einführung in die Programmierung mit Java

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 16/17. Kapitel 13. Listen. Listen 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 12. Listen. Listen 1

12. Dynamische Datenstrukturen

1. Typen und Literale (6 Punkte) 2. Zuweisungen (6 = Punkte)

Informatik II Prüfungsvorbereitungskurs

Datenstrukturen und Abstrakte Datentypen

Software Entwicklung 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12 1. Kapitel 11. Listen. Listen

Einstieg in die Informatik mit Java

Algorithmen und Programmierung III

Übung Algorithmen und Datenstrukturen

Prof. Dr. Uwe Schmidt. 30. Januar 2017

Datenstrukturen sind neben Algorithmen weitere wichtige Bausteine in der Informatik

Java. public D find(k k) { Listnode K, D n = findnode(k); if(n == null) return null; return n.data; Java

Grundlagen der Informatik / Algorithmen und Datenstrukturen. Aufgabe 132

JAVA KURS COLLECTION

Stapel (Stack, Keller)

1. Die rekursive Datenstruktur Liste

Lösungshinweise/-vorschläge zum Übungsblatt 11: Software-Entwicklung 1 (WS 2017/18)

Kapitel 9: Klassen und höhere Datentypen. Selektoren

Einführung Elementare Datenstrukturen. Der Konstruktor muß den Listenkopf head erzeugen. Der Vorgänger und Nachfolger von head ist head selbst.

Physikalisch Technische Lehranstalt Wedel 31. Januar 2004 Prof. Dr. Uwe Schmidt

4.4.1 Implementierung vollständiger Bäume mit Feldern. Reguläre Struktur: Nachfolger des Knoten i sind die Knoten 2*i und 2*i+1.

Datenstrukturen / Container in Java

Martin Unold INFORMATIK. Geoinformatik und Vermessung

Bäume. Text. Prof. Dr. Margarita Esponda SS 2012 O4 O5 O6 O ALP2-Vorlesung, M. Esponda

Beispiellösung zur Klausur AI2 im Sommersemester 2007

Aufgabenblatt 4. Aufgabe 3. Aufgabe 1. Aufgabe 2. Prof. Dr. Th. Letschert Algorithmen und Datenstrukturen

Stack und Queue. Thomas Schwotzer

Programmieren in Java

Software Entwicklung 1

Verkettete Listen. Implementierung von einfach verketteten Listen. Implementierung von doppelt verketteten Listen

Abstract Data Structures

Allgemeine Hinweise:

Datenstrukturen (66) Programmieren 2 - H.Neuendorf

Counting - Sort [ [ ] [ [ ] 1. SS 2008 Datenstrukturen und Algorithmen Sortieren in linearer Zeit

Institut für Programmierung und Reaktive Systeme. Java 7. Markus Reschke

! 1. Rekursive Algorithmen.! 2. Rekursive (dynamische) Datenstrukturen. II.3.2 Rekursive Datenstrukturen - 1 -

Bäume 1. Thomas Röfer

SS10 Algorithmen und Datenstrukturen 2. Kapitel Fundamentale Datentypen und Datenstrukturen

Übungsblatt Programmierung und Software-Entwicklung Generizität, Interfaces, Listen, Sortieralgorithmen & JUnit

Klausur zur Vorlesung Einführung in die Programmierung

Tutoraufgabe 1 (Implementierung eines ADTs):

Schein-/Bachelorklausur Teil 2 am Zulassung: Mindestens 14 Punkte in Teilklausur 1 und 50% der Übungspunkte aus dem 2. Übungsblock.

Algorithmen und Programmierung III

Anwendungsbeispiel MinHeap

1. Rekursive Algorithmen 2. Rekursive (dynamische) Datenstrukturen

Abgabe: (vor der Vorlesung) Aufgabe 3.1 (P) Master-Theorem

Transkript:

Ordnung im Materiallager: Datenstrukturen II Suchen und Sortieren im Array Verkettete Listen Rekursion

Indizierter Datenbehälter Modell: Parkhaus, nummerierte Plätze interface FuhrparkIndex { // indiziert public int hinzufuegen(fahrzeug fz); // liefert Index public int suchen(fahrzeug fz); // Vergleichsobjekt public Fahrzeug lesen(int index); public void loeschen(int index); public int anzahl(); (c)schmiedecke 04 Pr11-Datenstrukturen II 2

Implementierung mit einem Array class FuhrparkArray implements FuhrparkIndex { // private Attribute private Fahrzeug[] fahrz; private int anzahl = 0; // Standardkonstruktor, feste Groesse public FuhrparkArray() { fahrz = new Fahrzeug[50]; // Konstruktor mit Groessenangabe public FuhrparkArray(int groesse) { fahrz = new Fahrzeug[groesse]; (c)schmiedecke 04 Pr11-Datenstrukturen II 3

// Hinzufügen, sofern Platz ist public int hinzufuegen(fahrzeug fz) { if (anzahl >= fahrz.length) throw new VollException(anzahl); fahrz[anzahl] = fz; anzahl++; return anzahl-1; // hinzufügen public class VollException extends IndexOutOfBoundsException { public int anzahl() { return anzahl; // anzahl public class IndexException extends IndexOutOfBoundsException { // lesen, falls vorhanden public Fahrzeug lesen(int index) { if (index < 0 index >= fahrz.length) throw new IndexException(index); if (index >= anzahl) return null; // oder IndexException... return fahrz[index]; // lesen (c)schmiedecke 04 Pr11-Datenstrukturen II 4

public int suchen(fahrzeug fz) // Vergleichsobjekt throws NoObjectException { if (fz==null) throw new NoObjectException(); for (int i=0; i<anzahl; i++) if (fz[i].equals(fz)) return i; // gefunden return -1; // nicht gefunden // löschen und zusammenschieben public void loeschen(int index) { if (index <0 index >= anzahl) throw new IndexException(index); for (int i=index; i<anzahl-1; i++) fahrz[i] = fahrz[i+1]; // hochschieben fahrz[anzahl-1] = null; // ehem. letztes löschen anzahl --; // Fertig, Klassenende class NoObjectException extends Exception { (c)schmiedecke 04 Pr11-Datenstrukturen II 5

Sortieren im Array Die Klasse FuhrparkArray wird um die Methode sortieren() erweitert. Voraussetzung: Fahrzeug muss eine Methode groesser() enthalten. Hinweis: nach dem Sortieren sind alle bis dahin gelieferten Indizes ungültig! (c)schmiedecke 04 Pr11-Datenstrukturen II 6

Sortieren public int sortieren() { // "Bubblesort" // Idee: "schwere" Elemente sinken nach unten for (int i=anzahl-1; i>0; i--) { // rueckwärts Fahrzeug letztes = fahrz[i]; for (int k=i-1; k>=0; k--) { Fahrzeug vergleich = fahrz[k]; // vorgänger if (vergleich.groesser(letztes)) { //vertauschen: fahrz[i] = letztes; fahrz[k] = vergleich; letztes = vergleich; //neuer Vergleichswert // for k // for i // sortieren Invariante: Die letzen Einträge sind sortiert und größer als alle anderen. Umformulieren: leichte Elemente steigen auf... (c)schmiedecke 04 Pr11-Datenstrukturen II 7

Suchen im sortierten Array Der effizienteste Suchalgorithmus ist die Binäre Suche (BinSearch) Sie funktioniert nur im dichten Array (keine Lücken) Die Idee ist einfach: es wird jeweils ermittelt, in welcher Hälfte des Arrays der gesuchte Wert liegen muss. (c)schmiedecke 04 Pr11-Datenstrukturen II 8

Binäre Suche public int suchen(fahrzeug fz) {//"Binsearch" // Idee: Mitten ins Suchintervall greifen int min = 0, max = anzahl - 1; while (min <= max) { int mitte = (min + max) / 2; Fahrzeug fzm = fahrz[mitte]; if (fzm.groeser(fz)) min = mitte + 1; // hinten suchen else if (fz.eq(fzm)) return mitte; // gefunden else max = mitte - 1; // vorne suchen // while return 1; // nicht gefunden // suchen Invariante: Das gesuchte Element befindet sich zwischen min und max. (c)schmiedecke 04 Pr11-Datenstrukturen II 9

Alternative zu Arrays: Verkettete Listen Element Element class Node { // Knoten Element element; Node next; Element rekursive Definition ø (c)schmiedecke 04 Pr11-Datenstrukturen II 10

Einfügen Element Element Element Element ø void einfuegennach(knoten kn, Element el) { kn.naechster = new Knoten(el, kn.naechster); (c)schmiedecke 04 Pr11-Datenstrukturen II 11

Löschen Element Element Element ø void loeschennach(knoten kn) throws LeerException { try { kn.naechster = kn.naechster.naechster; catch (NullPointerException ex) { throw new LeerException("nix zu loeschen"); (c)schmiedecke 04 Pr11-Datenstrukturen II 12

Stack und Queue (Stapel und Warteschlange) Zwei sehr wichtige Datenbehälter-Typen Identische Schnittstelle, unterschiedliches Verhalten interface Container { void add(object o); Object remove(); interface LiFo extends Container { interface FiFo extends Container { (c)schmiedecke 04 Pr11-Datenstrukturen II 13

Array als LiFo class StackArray implements LiFo { private Object[] stack = new Object[size]; private int top = 0; public void add(object o) throws OverflowExc { if (top == size) throw new OverflowExc(); stack[top] = o; top++; public Object remove() throws UndeflowExc { if (top==0) throw new UndeflowExc(); top --; return stack[top+1]; (c)schmiedecke 04 Pr11-Datenstrukturen II 14

Liste Als LiFo stack class ListArray implements LiFo { private Node stack; public void add(object o) { if (stack==null) stack = new Node(o,null); else stack = new Node(o,stack); public Object remove() throws UndeflowExc { if (stack==null) throw new UndeflowExc(); Object o = stack.element; stack = stack.next; return o; (c)schmiedecke 04 Pr11-Datenstrukturen II 15

Array als FiFo class QueueArray implements FiFo { private Object[] queue = new Object[size]; private int first=0, count=0; last=0; void add(object o) throws OverflowExc { if (count>=size) throw new OverflowExc(); queue[last] = o; last = (last+1)%size; // modulo count ++; Object remove() throws UnderflowExc { if (count==0) throw new UnderflowExc(); Object o = queue[first]; count --; first = (first+1)%size; return o; next 11 10 9 (c)schmiedecke 04 Pr11-Datenstrukturen II 16 8 12 7 0 6 1 2 3 4 5

Liste als FiFo first last class ListQueue implements FiFo { private Node first=null, last=null; public void add(object o) { Node newnode = new Node(o, null); if (last==null) first = last = newnode; else last = last.next = newnode; public Object remove() throws UndeflowExc { if (first==null) throw new UndeflowExc(); Object o = first.element; first = first.next; if (first==null) last = null; return o; (c)schmiedecke 04 Pr11-Datenstrukturen II 17

Suchen in einer verketteten Liste Container, die durchsuchbar sind, sollen das Interface Searchable implementieren: interface Searchable { boolean contains(object o) first last (c)schmiedecke 04 Pr11-Datenstrukturen II 18

Iterative Lösung iterativ: schrittweise In der Programmierung bedeutet das "unter Verwendung einer Schleife" wo kann die NullPointer Exc. auftreten? public class LiFoSearchable extends LiFoList implements Searchable { public boolean contains(object o) { Node searchpt = first; try { while (true) { if (searchpt.element.equals(o)) return true; searchpt = searchpt.next; catch (NullPointer Exception ex) { return false; return false; // nur formal, wird nie erreicht. (c)schmiedecke 04 Pr11-Datenstrukturen II 19

Rekursive Lösung rekursiv: mit Bezug auf sich selbst. In der Programmierung bedeutet das, dass eine Methode sich selbst aufruft. Die Bedingungen müssen sich ändern (Parameter, Objektzustand), sonst kommt es zur Endlos-Rekursion! public class LiFoSearchableRek extends LiFoList implements Searchable { public boolean contains(object o) { return contains(first,o); Rekursion private boolean contains(node list, Object o) { try { if (list.element.equals(o)) return true; else return contains(list.next, o); catch (NullPointer Exception ex) { return false; (c)schmiedecke 04 Pr11-Datenstrukturen II 20

FiFo ohne last-zeiger public void add(object o) { Node newnode = new Node(o, null); if (first == null) first = newnode; else add(first, newnode); private add(node list, Node new){ try { add(list.next, new); catch (NullPointerException ex) { list.next = new; first last (c)schmiedecke 04 Pr11-Datenstrukturen II 21

Sortiert einfügen public void add(object o) { if (first == null) first = new Node(o,null); else first = add(first, o); // Methode gibt Liste mit Neueintrag zurück private Node add(node list, Node new){ if (list.element.greater(o) return new Node(o, list); // vorn einfügen, Ende! try { list.next = add(list.next, o); // in Rest einf. catch (NullPointerException ex) // gibt kein größeres { list.next = new Node (o,null); // hinten anhängen return list; (c)schmiedecke 04 Pr11-Datenstrukturen II 22

Array oder verkettete Liste?? Vorteile Array: Suchen und Sortieren einfach Indizierte Zugriff einfach (i-tes Element) Stack und WS einfach Vorteile verkettete Liste: keine Längenbeschränkung Speicherplatzbelegung nach Bedarf Mittiges Einfügen und Entnehmen ohne Verschieben Stack und WS einfach Wahl der Implementierung nach im Einzelfall entscheidet über Effizienz Implementierung von Interfaces erleichtert den Austausch (c)schmiedecke 04 Pr11-Datenstrukturen II 23

Fertige Datenbehälter Datenbehälter braucht man immer Es gibt eine große gemeinsame Schnittstelle aller Datenbehälter Auch die spezialisierten Schnittstellen und Verhalten sind standardisiert Die optimale Implementierung richtet sich nach dem Verwendungszweck Die Effizienz und Zuverlässigkeit hängt von der Implementierung ab Alles spricht für Fertigprodukte! (c)schmiedecke 04 Pr11-Datenstrukturen II 24

..aber davon reden wir das nächste Mal: Das Java-Collections-Famework. Nie mehr Datenbehälter selbst zimmern!