class ListElement { int value; ListElement next; ListElement() { next=null; value=0;

Ähnliche Dokumente
Algorithmen und Datenstrukturen

1 Polymorphie (Vielgestaltigkeit)

Folge 18 - Vererbung

Programmieren in Java

Verteilte Systeme CS5001

Java Einführung Collections

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 13. Bäume. Bäume

Java Einführung Abstrakte Klassen und Interfaces

3 Objektorientierte Konzepte in Java

Java: Vererbung. Teil 3: super()

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

3 Objektorientierte Konzepte in Java

HEUTE. Datenstrukturen im Computer. Datenstrukturen. Rekursion. Feedback Evaluation. abstrakte Datenstrukturen

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Musterlösungen zur Klausur Informatik 3

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Java Virtual Machine (JVM) Bytecode

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

Java-Schulung Grundlagen

einkonto.zahle(+100); //Transaktion Einzahlung einkonto.zahle(-20); //Transaktion Auszahlung einkonto.zahle(+30); //Transaktion Einzahlung

Struktur am Beispiel einer Liste

Tutorium 5 - Programmieren

Prinzipien Objektorientierter Programmierung

5. Tutorium zu Programmieren

Java Schulung (Java 2 Java Development Kit 5 / 6)

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Bäume. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 10: Collections 4. Inhalt. Bäume. Einführung. Bäume.

Programmentwicklung ohne BlueJ

7. Performance und Speicherauslastung

Kapitel 6. Vererbung

Vorkurs C++ Programmierung

Kapitel 6. Vererbung

Exercise (Part I) Anastasia Mochalova, Lehrstuhl für ABWL und Wirtschaftsinformatik, Kath. Universität Eichstätt-Ingolstadt 1

equals und hashcode SortedSet NavigableSet Assoziative Container Programmieren II Dr. Klaus Höppner Hochschule Darmstadt Sommersemester / 32

Grundlagen der Programmierung Prof. H. Mössenböck. 10. Klassen

Angewandte IT-Sicherheit

Distributed Computing Group

PIWIN 1 Übung Blatt 5

Objektorientierte Programmierung

Große Übung Praktische Informatik 1

Klassendefinitionen verstehen

Binärbäume. Prof. Dr. E. Ehses,

Objektorientierte Programmierung

Kapitel 7 des Buches, von Java-Selbstbau nach Scala-Library portiert Christoph Knabe

Aufgabenblatt Nr. 5 Generizität und TicTacToe

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Java Kurs für Anfänger Einheit 5 Methoden

Probeklausur: Programmierung WS04/05

Java - Programmierung - Objektorientierte Programmierung 1

UNIVERSITÄT ULM Fakultät für Ingenieurswissenschaften und Informatik Institut für Datenbanken und Informationssysteme

Kapitel 9. Inner Classes. 9.1 Wiederholung: Iteratoren. Ausführen einer Operation auf allen Elementen einer Containerklasse

Datenbankanwendungsprogrammierung Crashkurs Java

Informatik 11 Kapitel 2 - Rekursive Datenstrukturen

5.4 Klassen und Objekte

Client-Server-Beziehungen

Typische Probleme. 7. Performance und Speicherauslastung. Parameter von java mit Performance-Einfluss. Parameter von javac mit Performance-Einfluss

Abstrakte Datentypen.

Applet Firewall und Freigabe der Objekte

11: Echtzeitbetriebssystem ucos-ii

Praktische Übung 'JUnit-Test'

Grundlagen der Programmierung Prof. H. Mössenböck. 11. Objektorientierung

Kapitel 6. Vererbung

Programmieren in Java

Praktikum Informatik II Prof. Dr. Martin Trauth, Dr. Michael Männel

Bachelor-Klausur im WiSe 2013 / Grundlagen der Informatik

Ein Manager mit CardLayout layout/cards.java

Abteilung Informatik, JFC/Swing 2004 Diego Schmidlin V2.2

8 Zugriffstypen ( Zeiger )

Javakurs 2013 Objektorientierung

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Anleitung. Ein einfaches RMI-Beispiel. (ab Java 5.0) c Y. Pfeifer. (Juni 2014)

Objects First With Java A Practical Introduction Using BlueJ. Mehr über Vererbung. Exploring polymorphism 1.0

Java Einführung Methoden in Klassen

5.5.8 Öffentliche und private Eigenschaften

Allgemein: Klassen testbar machen. 5. Mocking. Mocks programmieren. Zusammenspiel von Klassen testen

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Modul 122 VBA Scribt.docx

10. Datenbanken und DBI Ties BerkeleyDB Datenbanken und DBI Oracle, Mysql und Proxy Server Ties tie

EINI WiMa/LW. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 11/12

Aufgabe 1. »Programmieren«, WS 2006/2007. Nino Simunic M.A.

Restschmutzanalyse Residual Dirt Analysis

Teil 1: Grundeigenschaften von Rechnern und Software

3. Konzepte der objektorientierten Programmierung

Selbststudium OOP Programmieren 1 - H1103 Felix Rohrer

Objektorientierte Programmierung. Kapitel 12: Interfaces

Software-Engineering Software-Management

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

Abschnitt 9: Schnittstellen: Interfaces

Versuchsziele Kenntnisse in der Anwendung von: Sortieren mit Klassen Benutzung von generischen Klassen o Definition o Sortierung.

Whitepaper. Produkt: combit Relationship Manager. Datensatzhistorie mit dem SQL Server 2000 und combit GmbH Untere Laube Konstanz

Java: Eine Übersicht. Dennis Giffhorn. Lehrstuhl für Programmierparadigmen Universität Karlsruhe

Institut fu r Informatik

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

Software Engineering Klassendiagramme Einführung

Prüfung Software Engineering II (IB)

Java Schulung. Objektorientierte Programmierung in Java Teil V: Die Java Collection Klassen. Prof. Dr. Nikolaus Wulff

Einführung in die Programmierung für Wirtschaftsinformatik

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

5. Threads, Serverprozesse und Benachrichtigungen

Generische Typen in Java 1.5. Die Erweiterung der Java Language Specification

Transkript:

Listenimplementierung Übung 1, Aufgabe 4. c 2004 Evgeny Matusov, Thomas Deselaers Zunächst definieren wir die Basisklasse für die Listenelemente, die gleichzeitig einen Verweis auf weitere Listenelemente beinhaltet: class ListElement { int value; ListElement next; ListElement() { next=null; value=0; Die folgende Klasse implementiert die Liste. Wir verwenden ListElement head als Anker für den Anfang der Liste (sein Inhalt wird nicht verwendet), sowie ListElement point um auf die Position vor dem aktuellen Listenelement zu verweisen und die Bewegung innerhalb der Liste zu ermöglichen. Das Listenende wird durch Setzen der Klassenvariable next auf null gekennzeichnet. Dazu beachten Sie auch folgende schematische Darstellung: / This class implements a linked list. The head is not part of the list elements. The point points to the element BEFORE the active element. +----+ head ->null is the empty list. +----+ list.empty()==true, list.end()==true. \ point head -> 2 -> 3 ->null is a list containing a 2 and a 3. \ point in this case, getvalue returns the 2. list.empty()==false, list.end()==false head -> 2 -> 3 ->null is a list containing a 2 and a 3. \ point in this case, getvalue returns the 3. list.empty()==false, list.end()==false head -> 2 -> 3 ->null is a list containing a 2 and a 3. \ point in this case, getvalue fails. list.empty()==false, list.end()==true / Bei der Implementierung der Methoden der Klasse List ist der Sonderfall, dass das Ende der Liste erreicht ist, immer zu beachten. Eine Variante der Implementierung ist dann die folgende: class List { ListElement head, point; List() { // initialize the list head=new ListElement(); head.value=-1; // this value is not used 1

public boolean empty() { if(head.next==null) { else { public boolean end() { if(point.next==null) { else { public void next() { // go the next list element point=point.next; public void rewind() { // go back to the beginning of the list public int getvalue() { // get the value of the active element return point.next.value; else { return -1; public void setvalue(int val) { // set the value of the active element point.next.value=val; else { public void insert(int val) { // insertion BEFORE the active element // (which is point.next, not point!) ListElement n=new ListElement(); // reserve memory for the new element n.value=val; n.next=point.next; point.next=n; // adjust the pointers public void remove() { point.next=point.next.next; // automatic garbage collection else { 2

public void print() { ListElement akt=point; //save current point do { System.out.println(getValue()); next(); while(!end()); point=akt; // go back to the original point Für die Implementierung der doppelt verketteten Liste ist die folgende Basisklasse mit zwei Referenzierungsvariablen notwendig: class DoubleListElement { int value; DoubleListElement next; DoubleListElement prev; DoubleListElement() { next=null; prev=null; value=-1; In der unten vorgeschlagenen Implementierung der Klasse DoubleList verweist jetzt point auf das aktuelle Listenelement selbst. Diese Konvention erleichtert das Einfügen neuer Elemente. Schematisch ist die doppelt verkettete Liste so darstellbar: / This class implements a linked list. The point points TO the active element. +----+ null<- head ->null is the empty list. +----+ list.empty()==true, list.end()==true, \ point list.start()==true. null<- head <-> <-> ->null is a list containing a 2, a 3, and a 4. 2 3 4 +----+ +----+ +----+ \ point in this case, getvalue returns the 2. list.empty()==false, list.end()==false, list.start()==true. null<- 2 <-> 3 <-> 4 ->null is a list containing a 2, a 3, and a 4. \ point in this case, getvalue returns the 3. list.empty()==false, list.end()==false, list.start()==false. / Die Implementierung der Methoden ist im wesentlichen analog zu der einfach verketteten Liste. Die Methode start() prüft, ob der Zeiger prev auf null verweist oder nicht. Bei der Implementierung der in 3

der Aufgabenstellung geforderten Methode insertbefore() ist zu beachten, dass der Verweis next des vorherigen Elementes (das durch point.prev) erreichbar ist, entsprechend geändert werden muss, aber nur falls point nicht auf das erste Element der Liste verweist. Im Sonderfall des Listenbeginns muss head das gerade eingefügten neuen Element referenzieren, da das Einfügen vor dem Listenanfang stattfinden soll. class DoubleList { DoubleListElement head, point; DoubleList() { head=new DoubleListElement(); head.value=-1; public boolean empty() { if((head.next==null)&&(head.prev==null)) { else { public boolean end() { if(point.next==null) { else { public boolean start() { if(point.prev==null) { else { public void next() { point=point.next; public void back() { if(!start()) { point = point.prev; public void rewind() { 4

public int getvalue() { return point.value; // note: the point value itself is printed, // not the point.next.value! else { return -1; public void setvalue(int val) { point.value=val; // note: the point value itself is set, // not the point.next.value! else { public void insertbefore(int val) { DoubleListElement n=new DoubleListElement(); n.value=val; n.prev = point.prev; n.next = point; // the active element is referenced // by the inserted element as the next element if(!start()) { point.prev.next = n; // the previous element references // the inserted element as the next one else { head = n; point.prev = n; // the inserted element is the new list beginning // the inserted element is // the new previous element for the active element public void print() { DoubleListElement akt=point; //save point do { System.out.println(getValue()); next(); while(!end()); point=akt; //restore point Die hier vorgeschlagene Implementierungen von Stack und Queue greifen auf die Methoden der Klasse List zu, d. h. die Klassenvererbung von Java wird ausgenutzt. Alternativ könnte man auch die entsprechende Klassen vollständig neu implementieren, also im wesentlichen die Methoden insert() und remove() modifizieren. Beim Stack wird immer am Anfang der Liste ein Element eingefügt und auch entfernt: class Stack extends List { public void push(int val) { insert(val); 5

public int pop() { int x = getvalue(); remove(); return x; Bei der Queue, in der unten vorgeschlagenen Implementierung, wird ein neues Element immer am Ende der Liste einfefügt (Aufruf von insert-methode gefolgt von next()). Um dann vom Anfang der Queue die Elemente rauszunehmen, und dann wieder am Ende weiter zu schreiben, benötigt man einen zusätzlichen Verweis, der als verborgene Variable endpoint gespeichert wird. class Queue extends List { private ListElement endpoint; public void put(int val) { insert(val); next(); public int get() { endpoint = point; // save the end position int x = getvalue(); remove(); point = endpoint; // return to the end position return x; Der Testdurchlauf wird in der main()-methode der Klasse ListTest implementiert. Bei dem Aufgabenteil a) ist folgendes zu beachten: In den Codezeilen gekennzeichnet mit!!! wird durch Aufruf von insert() neuer Speicher reserviert. Obwohl eine dritte Liste nicht verwendet wird, kommt man mit dem bisher vorhandenen Speicher nicht aus. Das liegt daran, dass in Java die Klassenvariablen (hier: die Verweise head und point) in Objekten eingekapselt sind. Sie können nicht als ( call-by-reference ) Parameter an die Methoden der gleichen Klasse übergeben werden, die ein anderes Objekt der Klasse aufruft. Aus diesem Grund ist Java für die Implementierung solcher Listenoperationen nicht besonders geeinigt. Das Testen der doppelt verketteten Liste, sowie vom Stack und von der Queue, besteht aus Einfügungen von Elementen und Ausgabe eines bestimmten Elementes. class ListTest { public static void main(string args[]) { int k; List liste1=new List(); List liste2=new List(); System.out.println("Trying to remove from empty list..."); liste1.remove(); // Output: ERROR liste1.insert(i); for(int i=1;i<=15;++i) { liste2.insert(-i); // fill the first list with elements // fill the second list with elements 6

System.out.println("Merging two lists into List 1..."); // Aufgabe 4 Teil a) liste1. liste2. while(!liste1.end()&&!liste2.end()) { liste1.insert(liste2.getvalue()); //!!! liste1.next(); // skip the just inserted element liste1.next(); // skip the next (previously present) element liste2.next(); // go to the next element in the second list while(!liste2.end()) { liste1.insert(liste2.getvalue()); //!!! liste1.next(); // skip the just inserted element liste2.next(); // go to the next element in the second list System.out.println("List 1 after merging:"); liste1.print(); // should be printed: // -15 10-14 9-13 8-12 7-11 6-10 5-9 4-8 3-7 2-6 1-5 -4-3 -2-1 // System.out.println("Testing the double linked list (going back 4 elements)..."); DoubleList d = new DoubleList(); d.insertbefore(i); d.back(); d.back(); d.back(); d.back(); // go back 4 Elements System.out.println(d.getValue()); // 7 should be printed // System.out.println("Testing the stack..."); Stack st = new Stack(); st.push(i); k = st.pop(); k = st.pop(); System.out.print("The value pushed before last: "); System.out.println(k); // 9 should be printed // System.out.println("Testing the queue..."); Queue q = new Queue(); q.put(i); k = q.get(); k = q.get(); System.out.print("The value put as second: "); System.out.println(k); // 2 should be printed 7