Kapitel 3 Elementare Datenstrukturen TexPoint fonts used in EMF.

Slides:



Advertisements
Ähnliche Präsentationen
Eine dynamische Menge, die diese Operationen unterstützt,
Advertisements

Kapitel 3 Arithmetische Schaltkreise
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (26-Graphenalgorithmen: Wiederholung und Übung) Prof. Th. Ottmann.
Wiederholung TexPoint fonts used in EMF.
Wiederholung TexPoint fonts used in EMF.
Wiederholung: Ziehen von Elementen
Sortieren I - Bubblesort -
Übungsbetrieb Di neuer Raum HZO 60
LS 2 / Informatik Datenstrukturen, Algorithmen und Programmierung 2 (DAP2)
Wiederholung Operationen auf Mengen Relationen, Abbildungen/Funktionen
Lineare Suche Divide-and-Conquer-Suche Kombinationssuche
<d,a,s, ,i,s,t, ,e,i,n,e, ,L,i,s,t,e>
Kapitel 3: Listen Lineare Liste: endliche Folge von Elementen eines Grundtyps (n>=0), leere Liste falls n=0 Listenelemente besitzen.
Gliederung Motivation / Grundlagen Sortierverfahren
Sortierverfahren Richard Göbel.
Sortierverfahren Richard Göbel.
Motivation Richard Göbel.
Algorithmen und Datenstrukturen
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (10 - Suchverfahren) T. Lauer.
Halbzeit: Kurze Wiederholung
Vorlesung Informatik 2 Algorithmen und Datenstrukturen Halbzeit: Was haben wir bisher gelernt? Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (27 – Kürzeste Wege) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.

Wiederholung Formale Potenzreihen
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 11 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
Operationen auf verketteten Listen
PKJ 2005/1 Stefan Dissmann Zusammenfassung der Vorwoche Variable stehen für (einen) Wert, der sich im Programmablauf ändern kann. Variablen besitzen einen.
Primzahlen Primzahlen sind natürliche Zahlen, die nur durch sich selbst und durch 1 teilbar sind? Bedingung: Die Zahl muss größer sein als 1.
FH-Hof Algorithmen und Datenstrukturen - Einführung Richard Göbel.
Diplomarbeit von Daniel Tameling
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 13: (Container-)Datenstrukturen.
2. Die rekursive Datenstruktur Baum 2
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Sortieralgorithmen Sortieren von Arrays.
Chair of Software Engineering Einführung in die Programmierung Prof. Dr. Bertrand Meyer Lecture 13: (Container-)Datenstrukturen.
Grundlagen der Programmierung
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Institut für Theoretische Informatik
Institut für Theoretische Informatik
Institut für Theoretische Informatik
Institut für Theoretische Informatik
1.6 Die Datenstruktur Stapel Ein Stapel (Stack) ist ein Sonderfall einer Liste. Die Elemente werden nach dem Prinzip LIFO (Last In First Out) angefügt.
Institut für Theoretische Informatik
Einfach und doppelt verkettete Listen in JAVA by Jens Weibler
Grundlagen der Algorithmen und Datenstrukturen Kapitel
Christian Scheideler WS 2008
Diskrete Mathematik Angelika Steger Institut für Theoretische Informatik TexPoint fonts used in EMF. Read the TexPoint manual before.
Programmiersprachen II Fortsetzung Datenstrukturen Hashing Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Programmiersprachen II Fortsetzung Datenstrukturen Einfache Bäume Übung 13 Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Pointer, Arrays und verkettete Listen. Mehrdimensionale Arrays  Pointer auf ein Array von Pointern  int32 **matrix = new int32*[3];  matrix: Zeiger.
Tutorium Software-Engineering SS14 Florian Manghofer.
Wiederholung Größte gemeinsame Teiler Satz von Bezout:
Wiederholung Gerichtete Graphen Digraph D=(V,E)
Wiederholung TexPoint fonts used in EMF.
Übungen Übungsanmeldung Übungskorrektur
Organisatorisches DiMa für Master of Science Mathe anrechenbar
Fragestunden & Übungsschein
TexPoint fonts used in EMF.
TexPoint fonts used in EMF.
Klausurtermin Klausur Diskrete Mathematik I Do stündig
Wiederholung TexPoint fonts used in EMF.
Wiederholung Körper K Eigenschaften von multiplikativen Gruppen
Kleiner Schreibfehler
Wiederholung Umwandlung in Koordinatenform
Zusammenfassung Königsberger Brückenproblem Planare Graphen
Wiederholung Verband Ungerichtete Graphen Partielle Ordnung
 Präsentation transkript:

Kapitel 3 Elementare Datenstrukturen TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AA

3.1 Grundlegendes Elementare Datenstrukturen: Arrays (Felder) Verkettete Listen bilden die Bausteine für abstrakte Mechanismen, die ausgehend von niederen Ebenen aufgebaut sind und Algorithmen mit zunehmender Komplexität ermöglichen

3.2 Arrays (Felder) Arrays: Eine feste Sammlung von Daten desselben Typs, die zusammen-hängend gespeichert und über einen Index zugängig sind Fundamentale Datenstruktur: Direktes Abbild des Speichersystems. Ein Arrayzugriff a[i] wird in nur wenige Maschinenanweisungen übersetzt  Programme mit Arrays werden in effiziente Maschineprogramme übersetzt.

3.2 Arrays (Felder) Beispiel: Das Primzahlensieb des Eratosthenes Ältester und bekanntester Siebalgorithmus, benannt nach Eratosthenes (ca. 200 v. Chr.) Prinzip von Siebalgorithmen: Eine Menge von Elementen wird in zwei Klassen aufgeteilt: die guten und die schlechten Elemente. Schlechte Elemente sind einfacher zu finden als gute. Ein Siebprozess eliminiert sukzessive Elemente, die als schlecht erkannt wurden. Jedes eliminierte Element hilft, weitere schlechte Elemente zu erkennen. Die überlebenden Elemente müssen die guten sein. Siebalgorithmus für Primzahlen: gut = ist eine Primzahl schlecht = ist keine Primzahl Der älteste und am besten bekannte Siebalgorithmus ist benannt nach Eratosthenes, der ca. 200 v. Chr. gelebt hat. Siebalgorithmen liegt das folgende Prinzip zugrunde: … Siebalgorithmen sind häufig anwendbar, wenn …

3.2 Arrays (Felder) Primzahlensieb von Eratosthenes: Alle Primzahlen kleiner gleich n ausgeben Markiere die kleinste Primzahl, d.h. 2, und entferne alle ihre Vielfachen innerhalb des gewünschten Bereichs 1 … n. Die kleinste verbleibende Zahl muß prim sein, markiere sie und entferne wieder alle ihre Vielfachen. Wiederhole diesen Prozess für alle Zahlen bis (Falls eine ganze Zahl c <= n faktorisiert werden kann als c = a · b, so muß entweder a <= oder b <= gelten) Das Primzahlensieb von Eratosthenes funktioniert wie folgt: …

3.2 Arrays (Felder) Das Primzahlensieb von Eratosthenes funktioniert wie folgt: …

3.2 Arrays (Felder) static void eratosthenes(int n) { int sqrtn = (int) Math.floor(Math.sqrt((double) n)); Sieve s = new Sieve(n); int p = 2; while (p <= sqrtn) { int i = p * p; while (i <= n) { s.remove(i); i = i + p; } do p++; while (! s.isMember(p)); } int c = 0; for (int i = 2; i <= n; i++) if (s.isMember(i)) { c++; System.out.println("prim(" + c + ") = " + i); } } Der JAVA-Code sieht folgendermaßen aus: … Dabei benutzen wir als Sieb ein Objekt der Klasse Sieve, deren Implementierung wir uns gleich näher ansehen werden.

3.2 Arrays (Felder) public class Sieve { public final int n; // Groesse des Sieve private static final int ws = 64; // Anzahl Bit in long private final int as; // Groesse des Arrays private long[] s; // zur Speicherung des Sieve // Konstruktor public Sieve(int n) { this.n = n; as = (n + ws - 1) / ws; s = new long[as]; for (int i = 0; i < as; i++) s[i] = ~0L; }

3.2 Arrays (Felder) // public Methoden /** * Liefert "true" zurueck, falls das Element im * Sieve enthalten ist, sonst "false". */ public boolean isMember(int e) { if ((1 <= e) && (e <= n)) { int i = (e - 1) / ws; e = (e - 1) % ws; return ((s[i] & (1L << e)) != 0); } else return false; }

3.2 Verkettete Listen Listenstrukturen = dynamische Datenstrukturen Mithilfe von Einfüge- und Löschoperationen können Listenstrukturen zur Laufzeit nicht nur die gespeicherten Datenwerte, sondern auch ihre Größe und Struktur verändern Listen: Schlüsselidee Alloziere benötigten Speicherplatz nicht wie beim Array in einem großen zusammenhängenden Teil, sondern dynamisch in kleinen Fragmenten, die ein gegebenes Objekt speichern können Verknüpfung von Datenelementen, die verstreut im Speicher liegen, erfolgt durch Zeiger bzw. Referenzen, d.h. Speicheradressen, an denen die Elemente gegenwärtig abgelegt sind Das Spektrum der Datenstrukturen reicht von statischen Objekten, wie einer Tabelle von Konstanten, zu dynamischen Strukturen wie Listen. Listen erlauben nicht nur, die gespeicherten Datenwerte zu ändern, sondern auch die Größe und Struktur der Liste können sich zur Laufzeit auf Grund von Einfüge- und Löschoperationen oder Reorganisationen verändern. Die meisten der bisher diskutierten Datenstrukturen können ihre Größe und Struktur nur eingeschränkt verändern. Ein zirkulärer Puffer z.B. unterstützt Einfügen an einem und Löschen am anderen Ende und kann bis zu einer vorgegebenen maximalen Größe wachsen. Ein Heap unterstützt Löschen an einem Ende des Arrays, und Einfügen irgendwo im Array. In einer Liste kann jede lokale Veränderung mit einem Aufwand durchgeführt werden, der unabhängig von der Größe der Liste ist - vorausgesetzt wir kennen die Speicherpositionen der involvierten Elemente. Die Schlüsselidee, um diese Forderung zu erfüllen, besteht darin, benötigten Speicherplatz nicht mehr wie beim Array in einem großen zusammenhängenden Teil zu allozieren, sondern den benötigten Speicherplatz dynamisch in kleinen Fragmenten anzulegen, die ein gegebenes Objekt speichern können. Da dann die Datenelemente mehr oder weniger zufallsmäßig verstreut und nicht zusammenhängend im Speicher abgelegt werden, erzeugt eine Einfüge- oder Löschoperation keinen Dominoeffekt, durch den andere Datenelemente herumgeschoben werden. Ein Element wird irgendwo im Speicher abgelegt und mit anderen Elementen durch sogenannte Zeiger oder Referenzen (d.h. Speicheradressen, an denen die Elemente gegenwärtig abgelegt sind) verknüpft.

3.2 Verkettete Listen Zeiger oder Referenz Ein Sprachkonstrukt, das in modernen Programmiersprachen benutzt wird, um das Äquivalent einer Speicheradresse darzustellen Im wesentlichen eine Speicheradresse, kann aber mehr Informationen enthalten: In Java oder anderen streng getypten Sprachen beziehen sich Zeiger bzw. Referenzen auch auf die Typdefinitionen der Objekte, auf die sie verweisen  Übersetzer kann die konsistente Benutzung von Zeiger- bzw. Referenzvariablen sicherstellen Zeigervariable bzw. Referenzvariable nimmt Speicheradressen als Werte an Ein gelöschtes Element hinterläßt keine Lücke, die wie beim Array gefüllt werden müßte. Stattdessen hinterläßt es freien Speicherplatz, der durch einen Speicherplatzverwalter (garbage collector) wieder eingesammelt wird. Ein gelöschtes Element wird wahrscheinlich einige Verbindungslinks aufbrechen, durch die andere Elemente miteinander verknüpft werden. Falls dem so ist, so werden diese Elemente durch neue Links wieder miteinander verknüpft. Ein Zeiger oder eine Referenz ist ein Sprachkonstrukt, das in modernen Programmiersprachen benutzt wird, um das Äquivalent einer Speicheradresse darzustellen. Ein Zeiger bzw. eine Referenz ist im wesentlichen eine Speicheradresse, kann aber mehr Informationen enthalten. In Java oder anderen streng getypten Sprachen wie Pascal beziehen sich Zeiger bzw. Referenzen auch auf die Typdefinitionen der Objekte, auf die sie verweisen. Dies ermöglicht dem Übersetzer, die konsistente Benutzung von Zeiger- bzw. Referenzvariablen sicherzustellen. Eine Zeigervariable bzw. Referenzvariable nimmt als Werte Speicheradressen an.

3.2 Verkettete Listen Definition: Eine verkettete Liste ist eine Menge von Elementen, bei der jedes Element zu einem Knoten gehört, der auch eine Verbindung zu einem Knoten enthält. head tail null e1 e2 ei ... ei+1 en public class ListNode<E> { private E element = null; private ListNode<E> next = null; public ListNode() { }; public ListNode(E element) { this.element = element; } Illustrieren wir diese Konzepte am Beispiel der linearen Liste: Eine lineare Liste ist eine Folge von Knoten. Der erste Knoten ist der Kopf der Liste, der letzte der Schwanz. Abgesehen vom Schwanz zeigt jeder Knoten auf den nachfolgenden. Da der Schwanz keinen Nachfolger hat, erhält sein Zeiger den vordefinierten Wert null. Zugriff auf die Liste erfolgt über einen externen Zeiger head. Ist die Liste leer, so hat head den Wert null. Ein Listenknoten speichert ein Datenelement ei und einen Zeiger auf den nachfolgenden Listenknoten. Das Klasseninterface eines Knotens in Java könnte folgendermaßen aussehen: …

3.2 Verkettete Listen public void setNextNode(ListNode next) { this.next = next; } public ListNode<E> getNextNode() { return next; } public void setData(E element) { this.element = element; } public E getData() { return element; } } // class ListNode Implementierung Fortsetzung …

3.2 Verkettete Listen Einfügen eines neuen Knotens als Nachfolger eines Knotens, gegeben durch den Zeiger p: q = new ListNode<E>(y); q.setNextNode(p.getNextNode()); p.setNextNode(q); y q q.next = p.next; p.next = q; Abkürzende Schreibweise, die aber nicht den Grundsätzen der objekt-orientierten Programmierung (Zugriff auf in einer Klasse gekapselte Attribute nur über spezielle Zugriffsmethoden!) entspricht und daher so nicht in Programmen verwendet werden sollte! Lokale Operationen, wie das Einfügen oder Löschen an einer durch einen Zeiger p vorgegebenen Position, lassen sich effizient durchführen. Durch die folgenden Anweisungen wird ein neuer Knoten als Nachfolger eines Knotens eingefügt, auf den der Zeiger p verweist: … Im folgenden werde ich eine abgekürzte Schreibweise benutzen, die … head tail null e1 e2 ei ... ei+1 en p

3.2 Verkettete Listen Löschen des Nachfolgers eines Knotens, gegeben durch den Zeiger p: p.next = p.next.next; head tail null e1 e2 ei–1 ... ei en ei+1 p Der Nachfolger eines Knotens, auf den der Zeiger p verweist, wird durch die folgende Anweisung gelöscht: …

3.2 Verkettete Listen Erzeugung einer Liste: ListNode<Integer> head, tmp; head = new ListNode<Integer>(0); tmp = head; for (int i = 1; i < 4; i++) { tmp.next = new ListNode<Integer>(i); tmp = tmp.next; } tmp head null i 1 2 null 3 1 null 2 3 null tmp tmp tmp Betrachten wir als Beispiel eine Liste, deren Elemente vom primitiven Datentyp int sind … Eine solche Liste können wir z.B. folgendermaßen erzeugen: … Will man die Listenelemente ausgeben, so erreicht man dies durch Traversierung: …

3.2 Verkettete Listen Traversierung der Liste (Ausgabe): tmp = head; while (tmp != null) { System.out.println(tmp.data + " "); tmp = tmp.next; }  Ausgabe: 0 1 2 3 tmp tmp Betrachten wir als Beispiel eine Liste, deren Elemente vom primitiven Datentyp int sind … Eine solche Liste können wir z.B. folgendermaßen erzeugen: … Will man die Listenelemente ausgeben, so erreicht man dies durch Traversierung: …