300 likes | 526 Views
Fakultät für Wirtschaftswissenschaften. Einführung in die Programmierung Behälter-Klassen / Container-Klassen. Uwe Lämmel. www.wi.hs-wismar.de/~laemmel Uwe.Laemmel@hs-wismar.de. Inhalt . Datenbehälter – Container – Collection Zugriff bestimmt Verhalten abstrakter Datentyp Schlange
E N D
Fakultät für Wirtschaftswissenschaften Einführung in die ProgrammierungBehälter-Klassen / Container-Klassen Uwe Lämmel www.wi.hs-wismar.de/~laemmel Uwe.Laemmel@hs-wismar.de
Inhalt • Datenbehälter – Container – Collection • Zugriff bestimmt Verhalten • abstrakter Datentyp • Schlange • Keller • Baum • Tabelle
Datenbehälter – Container – Collection • Verwaltung von Objekten • Standardisierte Zugriffsoperationen • Implementation verbergen • Abstrakte Datentypenabstrakt: Abstraktion von Implementation
Datenbehälter – Container – Collection • Schlange (queue) First In First Out: FIFODruckerwarteschlange, Tastaturpuffer, … • Keller (Stack, Stapel) Last In First Out : LIFOMethoden-Stack, Compilieren von Programmen, … • Tabelle (table) Zugriff über SchlüsselDatenbanken • Baum (tree) HierarchieDatenbanken, Suchen, Sortieren, … • Liste (list, Folge) vor-zurück-anfang-endeZeileneditor, Grundstruktur für Container • Menge (set) jedes Element nur einmal
Schlange - Interface Interface: • Definition einer Schnittstelle (Vertrag) • nur Methoden-Köpfe! • Implementierung durch Klasse interface QueueIf { void insert (Object ob); // fügt am Ende ein Object getFirst ( ); // Element am Anfang void remove ( ); // löscht erstes Element int length ( ); // Anzahl der Element boolean isEmpty ( ); // Test, ob leer } //QueueIF
“Tom“ “Anna“ “Paula“ “Max“ “Lea“ Die Schlange – verkettete Liste • Einfügen first last • Wir benötigen: • Elemente (Objekte), die Inhalt (Name) und Referenz (auf Objekt)verwalten class Element • Löschen
obj: “Inhalt“ next: Elemente der Schlange class Element { private Object obj; private Element next; public Element ( ) { obj= null; next=null; } public Element (Object ob) { obj= ob; next=null; } public void setObject (Object ob) { obj=ob; } public void setNext (Element x) { next=x; } public Object getObject ( ) { return obj; } public Element getNext ( ) { return next; } }//Element
“Tom“ “Anna“ “Paula“ “Max“ first last Die Schlange – verkettete Liste class QueueEl implements QueueIF { private Element first;private Element last; public QueueEl( ){ first=last=null; } publicvoid insert(Object ob){ ... } public Object getFirst ( ) { if (isEmpty()) returnnull; elsereturn first.getObject( ); }//getFirst
Testrahmen Schlange publicstaticvoid main(String[ ] args) throws Exception { char c = 'x'; boolean ende = false; QueueEl p = new QueueEl( ); LineIO io = new LineIO( ); do { c=io.readChar( "eXit Insert Remove ... : "); // Kommando lesen switch (c) { // Auswahl der Aktion: case 'x': ende = true; break; case 'i': s = io.readString(" ... "); p.insert(s); break; case 'f': io.writeln("Spitze: "+p.getFirst( )); break; ... default: io.writeln(" Eingabe nicht verstanden :-( "); } //switch } while(!ende); // wiederhole, solange noch nicht ende erreicht
mehrfache Alternative: switch-Anweisung switch (Ausdruck) { case Ausdruck1 : Anweisungen1 case Ausdruck2 : Anweisungen2 ... case AusdruckN : AnweisungenN default : Anweisungen } //switch switch (i) { case1 : wort="eins"; break; case2 : wort="zwei"; break; case3 : case4 : wort="einige"; break; default : wort="viele"; } //switch
switch-Anweisung: Interpretation switch (Ausdruck) {case Ausdruck1: Anweisungen ... } • Ausdruck im Kopf vom Typ int,char, byte, short, oder long • Jeden Teil mit break beenden, falls kein weiterer case-Teil beachtet werden soll! Interpretation: Der Ausdruck wird ausgewertet und mit den Ausdrücken 1 bis N der Reihe nach verglichen.Stimmen beide überein, wird die Bearbeitung an dieser Stelle fortgesetzt. Gibt es keine Übereinstimmung wird der default-Teil ausgeführt (sofern vorhanden).
mehrfache Alternative: else-if-Anweisung if (Ausdruck== Ausdruck1) {Anweisungen1 } else if (Ausdruck == Ausdruck2) { Anweisungen2} ... else if (Ausdruck == AusdruckN) { AnweisungenN} else { //default Anweisungen } //if if (i== 1) wort ="eins"; else if (i== 2 ) wort ="zwei"; else if (i== 3 || i== 4 ) wort ="einige"; else wort ="viele"; switch kann immer durch else-if ersetzt werden! Umgekehrt: else-if durch switch ersetzen?
Aufgabe Schlange – Array • Entwickeln Sie eine zweite Implementation einer Schlange: Klasse QueueA. • Realisieren Sie mit der Klasse QueueA das Interface QueueIF • Benutzen Sie ein Array zum Speichern der Zeichenketten in der Schlange • Entwickeln Sie eine ausführbare Klasse zum Testen der Schlange (main-Methode) • Zusatzaufgabe: Wie kann eine Schlange mittels ArrayList realisiert werden?
Stack – Keller - Stapel Methoden: push – Objekt auf den Stapel legen peek – Oberstes Element zurückgeben pop – Oberstes Element löschen depth – Tiefe des Kellers = Anzahl Elemente isEmpty – Ist der Keller leer?
3. umgedreht wird 2. Reihenfolge 1. Die 0. Stack-Anwendung Stack s1 = new Stack(4); s1.push(“Die“); s1.push(“Reihenfolge“); s1.push(“wird“); s1.push(“umgedreht“); io.writeln(s1.top( )); // Ergebnis: „umgedreht“
java.util.Stack The Stack class represents a last-in-first-out (LIFO) stack of objects. It extends class Vector with five operations that allow a vector to be treated as a stack. java.lang.Object | +--java.util.AbstractCollection<E> | +--java.util.AbstractList<E> | +--java.util.Vector<E> | +--java.util.Stack<E> The usual push and pop operations are provided, as well as a method to peek at the top item on the stack, a method to test for whether the stack is empty, and a method to search the stack for an item and discover how far it is from the top.
Zusammenfassung • Keller (LIFO) • Schlange (FIFO) • Interface als Vertrag (öffentlich) • Klasse implementiert InterfaceImplementation verborgen • rekursive Datenstruktur: verkettete Liste • Testrahmen • switch-Anweisung
k B2 B1 (Binär)Baum Der leere Baum ist ein Baum. Sind B1, B2 Bäume und k ein Knoten und k nicht in B1 oder B2 enthalten, so ist auch ein Baum.
Bearbeite: einen Teilbaum, dann Wurzel/Knoten, dann anderen Teilbaum Reihenfolge ist Problem abhängig: links – wurzel – rechts rechts – wurzel – links links – rechts – wurzel wurzel – links – rechts Arbeiten mit Bäumen alf, bob, kai, max, pit,ray, tom, uwe
obj: “Inhalt“ :left right: Elemente eines Binärbaums class Tree { private Object obj; private Tree left;private Tree right; public Tree ( ) { obj= null; left=right=null;} public Tree (Object o) { obj=o; left=right=null;} public Tree (Object o, Tree l, Tree r) { obj=o; left=l; right=r; } public void setObject (Object o) { obj=o; } public void setLeft (Tree x) { left=x; } public Object getObject ( ) { return obj; } public Tree getLeft ( ) { return left; } ... } //Tree
k B2 B1 Binärer Suchbaum • nur für Elemente, für die eine Ordnung existiert (vergleichbar) pat,tom,ulf,dan,ali,alf,eva,pit,ulf,udo,bee,bea,uli,bub • Suchbaum: • x, xB1: x<k • x, xB2: kx • B1, B2 - Suchbäume
Methoden auf (Such-) Bäumen • Sortiertes Einfügen in einen Baum • Suche in einem Baum • Anzahl der Knoten in einem Baum • Anzahl der Blätter in einem Baum • Tiefe eines Baumes • Ausgabe des Baumes • preorder (WLR – links wurzel-rechts) – Präfix-Notation • inorder (LWR) – aufsteigend sortiert • postorder (LRW) – Postfix-Notation • Test auf AVL-Baum
+3 1 +4 Baum: Rekursive Methoden – Anzahl Knoten publicint anzKnoten() { int anz = 1; // mind. akt. Knoten if(left!=null)anz += left.anzKnoten(); if(right!=null)anz += right.anzKnoten(); return anz; } //Tree
Baum: Rekursive Methoden publicvoid runInorder(IntIO io) { if(left!=null) left.runInorder(io); io.writeln( obj.toString() ); if(right!=null) right.runInorder(io); } //Tree publicvoid runInorder(IntIO io) { if(this.getLeft( )!=null) this.getLeft( ).runInorder(io); io.writeln(this.getObject( ).toString() ); if(this.getRight( )!=null) this.getRight( ).runInorder(io); } //Tree
Liste Methoden: • Operationen nur an der markierten Position • read • insert • remove • Operationen zum Verschieben der Markierung: • next • prev • pos1 • end Beispiel: Zeileneditor
“Tom“ “Anna“ “Paula“ “Max“ “Tom“ Liste – einfach verkettet liste • Einfügen: danach, eingefügtes Element ist aktuell aktuell Probleme am Listenanfang!
Klasse Liste (von Zeichenketten) class Liste { private Element liste;private Element aktuell; public Liste( ) { liste=aktuell=null; } public Liste(String neu) { liste = new Element(neu); aktuell = liste; } //Liste publicvoid insert(String ob) { Element neu = new Element(obj); if(aktuell==null) neu.setNext(liste); else neu.setNext(aktuell.getNext()); if(aktuell==null) liste = neu; else aktuell.setNext(neu); aktuell = neu; } //insert
Zusammenfassung • Datenbehälter verwalten mehrere Objekte • Datenbehälter haben definierte Zugriffsmöglichkeiten • Trennung von Interface und Implementation • interface definiert Nutzung einer Klasse • Baum-Operationen können (nur) mit rekursiver Programmierung implementiert werden • rekursive Datenstruktur • einfach verkettete Liste