Dynamische Datenstrukturen
Steffen Reith
Steffen.Reith@hs-rm.de
Hochschule RheinMain
5. Juni 2014
Lineare dynamische
Datenstrukturen
Einleitung
Bis jetzt: Untersuchung von (einigen) Algorithmen und deren Analyse
Dazu wurden nur Variablen und Arrays von fester Gr ¨oße benutzt Vorteil: Einfache Handhabung und Deklaration
Nachteile: Unflexibel, da eine feste Grenze existiert und evtl. sehr viel Speicher unn ¨otig verbraucht wird
Um diese Nachteile zu beseitigen ben ¨otigen wir Datenstrukturen, diedynamisch wachsen(und) schrumpfen
k ¨onnen.
Einleitung
Bis jetzt: Untersuchung von (einigen) Algorithmen und deren Analyse
Dazu wurden nur Variablen und Arrays von fester Gr ¨oße benutzt
Vorteil: Einfache Handhabung und Deklaration
Nachteile: Unflexibel, da eine feste Grenze existiert und evtl. sehr viel Speicher unn ¨otig verbraucht wird
Um diese Nachteile zu beseitigen ben ¨otigen wir Datenstrukturen, diedynamisch wachsen(und) schrumpfen
k ¨onnen.
Einleitung
Bis jetzt: Untersuchung von (einigen) Algorithmen und deren Analyse
Dazu wurden nur Variablen und Arrays von fester Gr ¨oße benutzt Vorteil: Einfache Handhabung und Deklaration
Nachteile: Unflexibel, da eine feste Grenze existiert und evtl. sehr viel Speicher unn ¨otig verbraucht wird
Um diese Nachteile zu beseitigen ben ¨otigen wir Datenstrukturen, diedynamisch wachsen(und) schrumpfen
k ¨onnen.
Einleitung
Bis jetzt: Untersuchung von (einigen) Algorithmen und deren Analyse
Dazu wurden nur Variablen und Arrays von fester Gr ¨oße benutzt Vorteil: Einfache Handhabung und Deklaration
Nachteile: Unflexibel, da eine feste Grenze existiert und evtl. sehr viel Speicher unn ¨otig verbraucht wird
Um diese Nachteile zu beseitigen ben ¨otigen wir Datenstrukturen, diedynamisch wachsen(und) schrumpfen
k ¨onnen.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout) Dieses Verbergen von Details von Datenstrukturen ist als
Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout) Dieses Verbergen von Details von Datenstrukturen ist als
Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout) Dieses Verbergen von Details von Datenstrukturen ist als
Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout)
Dieses Verbergen von Details von Datenstrukturen ist als Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout) Dieses Verbergen von Details von Datenstrukturen ist als
Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Datenstrukturen und Wiederverwertbarkeit
Ziel: Unsere Programme sollen wiederverwertbar sein (Verbesserung der Softwarequalit ¨at)
Programmierer sollen unsere Datenstrukturenleicht benutzen k ¨onnen
Die Implementierung solljederzeit ¨anderbarsein (ohne dass der Benutzer diese bemerkt)
Abstraktion von unn ¨otige Details (z.B. Speicherlayout) Dieses Verbergen von Details von Datenstrukturen ist als
Geheimnisprinzip
bekannt (Programming by contract). Solche Datenstrukturen sind auch alsabstrakte Datentypen (ADT)bekannt.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen.
Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen). Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen. Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen). Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen. Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen).
Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen. Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen). Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen. Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen). Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Abstrakte Datentypen
Konkrete Datentypen: Werden direkt aus den Basisdatentypen bzw. C++/Java/Ruby-Klassen konstruiert (wie schon bekannt).
Abstrakte Datentypen: Bestehen aus einer Spezifikation der Schnittstelle nach außen. Verf ¨ugbare Operationen und deren Semantik wird beschrieben.
Abstrakte Datentypen entsprechen Softwaremodulen (≜dem Prinzip des Klassenkonzepts in OO-Sprachen). Folgende Prinzipien kommen zum Einsatz:
Kapselung: Ein ADT darf nur ¨uber seine Schnittstellen benutzt werden
Geheimnisprinzip: Die interne Realisierung eines ADT ist verborgen
Das Geheimnisprinzip kommt schon bei den Basisdatentypen zur Anwendung.
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc. Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen: void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc. Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen: void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen: void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen: void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen:
void push(Obj data);(Daten auf den Stack legen)
Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen:
void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen:
void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen )
boolean is empty();(Test ob Stack leer)
Die Datenstruktur Stack
Eine einfache Datenstruktur ist der Kellerspeicher (engl.Stack).
Ein Stack ist die Verwirklichung desLIFO-Prinzips (LIFO - Last-In-First-Out-Speicher):
Beim Auslesen eines Elements kann nur auf daszuletzt gespeicherte Element zugegriffen werden
Die n ¨achste Ausleseoperation liefert das vorletzte Element, etc.
Anderer Name f ¨ur Stack:Stapel
Die Schnittstelle eines Stapels besteht aus vier Operationen:
void push(Obj data);(Daten auf den Stack legen) Obj pop();(Oberstes Element entfernen)
Obj top();(Oberstes Element auslesen und nicht entfernen ) boolean is empty();(Test ob Stack leer)
Ein Beispiel
Gegeben sei ein leerer Stack. Nachpush(7); push(12);
push(3); push(17);sieht der Stack wie folgt aus:
7 12 3 17
Und dreipop-Operationen ergeben 17, 3 und 12 (in dieser Reihenfolge). ¨Ubrig bleibt:
7
Mit Feldern k ¨onnen wir sicherlich leicht einen Stapel fester Gr ¨oße implementieren. Aber:
Wie machen wir das dynamisch?
Ein Beispiel
Gegeben sei ein leerer Stack. Nachpush(7); push(12);
push(3); push(17);sieht der Stack wie folgt aus:
7 12 3 17
Und dreipop-Operationen ergeben 17, 3 und 12 (in dieser Reihenfolge). ¨Ubrig bleibt:
7
Mit Feldern k ¨onnen wir sicherlich leicht einen Stapel fester Gr ¨oße implementieren. Aber:
Wie machen wir das dynamisch?
Ein Beispiel
Gegeben sei ein leerer Stack. Nachpush(7); push(12);
push(3); push(17);sieht der Stack wie folgt aus:
7 12 3 17
Und dreipop-Operationen ergeben 17, 3 und 12 (in dieser Reihenfolge). ¨Ubrig bleibt:
7
Mit Feldern k ¨onnen wir sicherlich leicht einen Stapel fester Gr ¨oße implementieren. Aber:
Wie machen wir das dynamisch?
Ein Beispiel
Gegeben sei ein leerer Stack. Nachpush(7); push(12);
push(3); push(17);sieht der Stack wie folgt aus:
7 12 3 17
Und dreipop-Operationen ergeben 17, 3 und 12 (in dieser Reihenfolge). ¨Ubrig bleibt:
7
Mit Feldern k ¨onnen wir sicherlich leicht einen Stapel fester Gr ¨oße implementieren. Aber:
Wie machen wir das dynamisch?
Ein Beispiel
Gegeben sei ein leerer Stack. Nachpush(7); push(12);
push(3); push(17);sieht der Stack wie folgt aus:
7 12 3 17
Und dreipop-Operationen ergeben 17, 3 und 12 (in dieser Reihenfolge). ¨Ubrig bleibt:
7
Mit Feldern k ¨onnen wir sicherlich leicht einen Stapel fester Gr ¨oße implementieren. Aber:
Wie machen wir das dynamisch?
Interne Darstellung der Daten
Wir ben ¨otigen eine Hilfsdatenstruktur:
struct Node *next; // Referenz
daten
Referenz (Zeiger) auf nächstes Objekt next
T data; // Nutzdaten }
in C/C++
struct Node {
Nutz−
Objekte dieses Hilfsdatentyps k ¨onnen leicht mitnewerzeugt werden.
Deutet die Referenznextauf kein anderesNode-Objekt, so wird der Wertnullverwendet.
In C++ wird derstructevtl. durch eine Klasse incl. Zugriffsmethoden implementiert.
Interne Darstellung der Daten
Wir ben ¨otigen eine Hilfsdatenstruktur:
struct Node *next; // Referenz
daten
Referenz (Zeiger) auf nächstes Objekt next
T data; // Nutzdaten }
in C/C++
struct Node {
Nutz−
Objekte dieses Hilfsdatentyps k ¨onnen leicht mitnewerzeugt werden.
Deutet die Referenznextauf kein anderesNode-Objekt, so wird der Wertnullverwendet.
In C++ wird derstructevtl. durch eine Klasse incl. Zugriffsmethoden implementiert.
Interne Darstellung der Daten
Wir ben ¨otigen eine Hilfsdatenstruktur:
struct Node *next; // Referenz
daten
Referenz (Zeiger) auf nächstes Objekt next
T data; // Nutzdaten }
in C/C++
struct Node {
Nutz−
Objekte dieses Hilfsdatentyps k ¨onnen leicht mitnewerzeugt werden.
Deutet die Referenznextauf kein anderesNode-Objekt, so wird der Wertnullverwendet.
In C++ wird derstructevtl. durch eine Klasse incl. Zugriffsmethoden implementiert.
Ablauf der Push-Operation
3 12 7
NULL
head
ptr 17 Schritt 1
ptr head Schritt 2
17 3 12 7
NULL
5
17 3 12 7
NULL
head 5
ptr Schritt 3
17 3 12 7
NULL 5
head Schritt 4
Ablauf der Push-Operation
3 12 7
NULL
head
ptr 17 Schritt 1
ptr head Schritt 2
17 3 12 7
NULL
5
17 3 12 7
NULL
head 5
ptr Schritt 3
17 3 12 7
NULL 5
head Schritt 4
Ablauf der Push-Operation
3 12 7
NULL
head
ptr 17 Schritt 1
ptr head Schritt 2
17 3 12 7
NULL
5
17 3 12 7
NULL
head 5
ptr Schritt 3
17 3 12 7
NULL 5
head Schritt 4
Ablauf der Push-Operation
3 12 7
NULL
head
ptr 17 Schritt 1
ptr head Schritt 2
17 3 12 7
NULL
5
17 3 12 7
NULL
head 5
ptr Schritt 3
17 3 12 7
NULL 5
head Schritt 4
Einige Hinweise zur C++-Implementierung
template <class T> class Stack {
private:
// Node<T> ist eigene Klasse (noch implementieren) Node<T> *head; // Zeiger auf top-Objekt
unsigned long numElements; // Anzahl der Elemente public:
Stack(); // Konstruktor
∼Stack(); // Destruktor
void push(T &elem);// ’elem’ auf Stack ablegen T pop();// ein Element vom Stack holen
bool isEmpty(); // Test ob Stack leer ist };
Einige Hinweise zur JAVA-Implementierung
public class Stack { static class Node {
NutzDatentyp element;
Node next;
// Konstruktor
// Manipulation von Referenz und Nutzdaten }
private Node head = null; // Oberstes Stackelement public void push (NutzDatentyp obj){
Node n = new Node(obj, head);
head = n;
}
// pop, top und is empty fehlen noch }
Generische Datentypen
Die Programmlogik einesint-Stacks unterscheidet sich nicht von der Programmlogik eines Stacks von Kundendatens ¨atzen.
Ziel: Die Implementierung sollte unabh ¨angig vomNutzdatentyp sein
.
Dazu dienen in C so genannte
”templates“ (vgl. List<Integer> myIntList). In JAVA verwendet man
”Generics“.
Solche parametrierbare abstrakte Datentypen sind als
”generische Datentypen“ bekannt.
Generische Datentypen
Die Programmlogik einesint-Stacks unterscheidet sich nicht von der Programmlogik eines Stacks von Kundendatens ¨atzen.
Ziel: Die Implementierung sollte unabh ¨angig vomNutzdatentyp sein.
Dazu dienen in C so genannte
”templates“ (vgl. List<Integer>
myIntList). In JAVA verwendet man
”Generics“.
Solche parametrierbare abstrakte Datentypen sind als
”generische Datentypen“ bekannt.
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at
is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen auf einen Stapel ergibt sich:
Operation Zeitkomplexit ¨at is empty O(1)
top O(1)
push O(1)
pop O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Stapelspeichern:
Speicherung lokaler Variablen von Unterprogrammen Speichern von R ¨ucksprungadressen
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen: append(Obj data);(H ¨ange ein Element hinten an)
Obj get();(Entferne ein Element am Ende) boolean is empty();(Test ob Queue leer)
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt
Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen: append(Obj data);(H ¨ange ein Element hinten an)
Obj get();(Entferne ein Element am Ende) boolean is empty();(Test ob Queue leer)
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen: append(Obj data);(H ¨ange ein Element hinten an)
Obj get();(Entferne ein Element am Ende) boolean is empty();(Test ob Queue leer)
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen:
append(Obj data);(H ¨ange ein Element hinten an)
Obj get();(Entferne ein Element am Ende) boolean is empty();(Test ob Queue leer)
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen:
append(Obj data);(H ¨ange ein Element hinten an) Obj get();(Entferne ein Element am Ende)
boolean is empty();(Test ob Queue leer)
Warteschlangen
EineWarteschlange(engl. Queue) ist die Verwirklichung des FIFO-Prinzips (FIFO - First In First Out)
Neue Elemente werdenhintenan die Schlange angef ¨ugt Alte Elemente werdenvorneaus der Warteschlange entfernt
Die Schnittstelle einer Warteschlange besteht aus den Operationen:
append(Obj data);(H ¨ange ein Element hinten an) Obj get();(Entferne ein Element am Ende)
boolean is empty();(Test ob Queue leer)
Ein Beispiel
Gegeben sei eine leere Warteschlange. Nachappend(7);
append(12);append(3);append(17); erhalten wir:
head
12 3 17
7
tail Und dreimalgetergibt dann7,12und3. Zur ¨uck bleibt die Warteschlange:
17
head tail
Ein Beispiel
Gegeben sei eine leere Warteschlange. Nachappend(7);
append(12);append(3);append(17); erhalten wir:
head
12 3 17
7
tail
Und dreimalgetergibt dann7,12und3. Zur ¨uck bleibt die Warteschlange:
17
head tail
Ein Beispiel
Gegeben sei eine leere Warteschlange. Nachappend(7);
append(12);append(3);append(17); erhalten wir:
head
12 3 17
7
tail Und dreimalgetergibt dann7,12und3. Zur ¨uck bleibt die Warteschlange:
17
head tail
Ein Beispiel
Gegeben sei eine leere Warteschlange. Nachappend(7);
append(12);append(3);append(17); erhalten wir:
head
12 3 17
7
tail Und dreimalgetergibt dann7,12und3. Zur ¨uck bleibt die Warteschlange:
17
head tail
Ablauf der Append-Operation (I)
Schritt 1
head ptr
tail
NULL
7 12 3
17
7 12 3
head
tail
NULL
ptr Schritt 2
NULL
ptr NULL
17 Schritt 3
3 7
head
tail
12
Ablauf der Append-Operation (I)
Schritt 1
head ptr
tail
NULL
7 12 3
17
7 12 3
head
tail
NULL
ptr Schritt 2
NULL
ptr NULL
17 Schritt 3
3 7
head
tail
12
Ablauf der Append-Operation (I)
Schritt 1
head ptr
tail
NULL
7 12 3
17
7 12 3
head
tail
NULL
ptr Schritt 2
NULL
ptr NULL
17 Schritt 3
3 7
head
tail
12
Ablauf der Append-Operation (II)
7 12
head
tail
NULL
ptr 17 3
Schritt 4
tail
7 12 3
head NULL
17 Schritt 5
Ablauf der Append-Operation (II)
7 12
head
tail
NULL
ptr 17 3
Schritt 4
tail
7 12 3
head NULL
17 Schritt 5
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen
Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig)
DieVerkettungsrichtungist wichtig! Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet
Annahme: Verkettungsrichtung w ¨are umgekehrt appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Ablauf der Get-Operation
Die Referenzheadkopieren
Dann die im Node enthaltenen Informationen kopieren
Die Referenzheadauf den Nachfolger deshead-Knotens setzen Uberfl ¨ussiges Element mit¨ deletefreigeben (in JAVA unn ¨otig) DieVerkettungsrichtungist wichtig!
Neue Elemente werden am
”Schwanz“ eingekettet Alte Elemente werden am
”Kopf“ ausgekettet Annahme: Verkettungsrichtung w ¨are umgekehrt
appendist einfach (Schwanz neu setzen)
getw ¨areschwierig, da keine Referenz auf das Vorg ¨angerelement existiert (⇒kompletteQueue durchlaufen)
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen einer Warteschlange ergibt sich:
Operation Zeitkomplexit ¨at
append O(1)
get O(1)
is empty O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Warteschlangen:
Warteschlangen von Prozessen in Betriebssystemen (vgl.kfifo.cim Linux Kern)
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen einer Warteschlange ergibt sich:
Operation Zeitkomplexit ¨at append O(1)
get O(1)
is empty O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Warteschlangen:
Warteschlangen von Prozessen in Betriebssystemen (vgl.kfifo.cim Linux Kern)
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen einer Warteschlange ergibt sich:
Operation Zeitkomplexit ¨at append O(1)
get O(1)
is empty O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Warteschlangen:
Warteschlangen von Prozessen in Betriebssystemen (vgl.kfifo.cim Linux Kern)
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen einer Warteschlange ergibt sich:
Operation Zeitkomplexit ¨at append O(1)
get O(1)
is empty O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Warteschlangen:
Warteschlangen von Prozessen in Betriebssystemen (vgl.kfifo.cim Linux Kern)
Laufzeiten & Anwendungen
F ¨ur die Zeitkomplexit ¨at von Operationen einer Warteschlange ergibt sich:
Operation Zeitkomplexit ¨at append O(1)
get O(1)
is empty O(1)
Grund: F ¨ur jede Operation sind nur endlich viele elementare Anweisungen auszuf ¨uhren.
Anwendungen von Warteschlangen:
Warteschlangen von Prozessen in Betriebssystemen (vgl.kfifo.cim Linux Kern)
Lineare Listen
Bis jetzt: Einf ¨ugen und Entfernen von Elementen nur am Anfang oder Ende der Datenstruktur.
Ziel: Daten sollen geordnet (also sortiert) verwaltet werden und die Datenstruktur soll wieder dynamisch sein
(⇒Ein- und Ausf ¨ugen an beliebigen Stellen der Datenstruktur) Die Schnittstelle einer linearen Liste besteht aus den Operationen:
insert(Obj data);(Element an der richtigen Stelle einf ¨ugen) Obj remove(Obj data);(Entferne das Element)
boolean is empty();(Test ob Liste leer)
Lineare Listen
Bis jetzt: Einf ¨ugen und Entfernen von Elementen nur am Anfang oder Ende der Datenstruktur.
Ziel: Daten sollen geordnet (also sortiert) verwaltet werden und die Datenstruktur soll wieder dynamisch sein
(⇒Ein- und Ausf ¨ugen an beliebigen Stellen der Datenstruktur)
Die Schnittstelle einer linearen Liste besteht aus den Operationen: insert(Obj data);(Element an der richtigen Stelle einf ¨ugen) Obj remove(Obj data);(Entferne das Element)
boolean is empty();(Test ob Liste leer)
Lineare Listen
Bis jetzt: Einf ¨ugen und Entfernen von Elementen nur am Anfang oder Ende der Datenstruktur.
Ziel: Daten sollen geordnet (also sortiert) verwaltet werden und die Datenstruktur soll wieder dynamisch sein
(⇒Ein- und Ausf ¨ugen an beliebigen Stellen der Datenstruktur) Die Schnittstelle einer linearen Liste besteht aus den Operationen:
insert(Obj data);(Element an der richtigen Stelle einf ¨ugen)
Obj remove(Obj data);(Entferne das Element) boolean is empty();(Test ob Liste leer)
Lineare Listen
Bis jetzt: Einf ¨ugen und Entfernen von Elementen nur am Anfang oder Ende der Datenstruktur.
Ziel: Daten sollen geordnet (also sortiert) verwaltet werden und die Datenstruktur soll wieder dynamisch sein
(⇒Ein- und Ausf ¨ugen an beliebigen Stellen der Datenstruktur) Die Schnittstelle einer linearen Liste besteht aus den Operationen:
insert(Obj data);(Element an der richtigen Stelle einf ¨ugen) Obj remove(Obj data);(Entferne das Element)
boolean is empty();(Test ob Liste leer)
Lineare Listen
Bis jetzt: Einf ¨ugen und Entfernen von Elementen nur am Anfang oder Ende der Datenstruktur.
Ziel: Daten sollen geordnet (also sortiert) verwaltet werden und die Datenstruktur soll wieder dynamisch sein
(⇒Ein- und Ausf ¨ugen an beliebigen Stellen der Datenstruktur) Die Schnittstelle einer linearen Liste besteht aus den Operationen:
insert(Obj data);(Element an der richtigen Stelle einf ¨ugen) Obj remove(Obj data);(Entferne das Element)
boolean is empty();(Test ob Liste leer)
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Die Remove-Operation
Angenommen wir haben die folgende sortierte Liste gegeben:
NULL
3 7 12 17
head
Es sollremove(12)simuliert werden:
1 Setze
”Vorg ¨anger“ aufhead.
2 R ¨ucke den
”Vorg ¨anger“ so lange vor, bis er auf ein Objekt deutet, dessennext-Referenz auf das Objekt deutet, das die zu
entfernenden Daten enth ¨alt.
3 Sichere die Referenz auf den direkten Nachfolger des
”Vorg ¨angerobjekts“ in die tempor ¨are ReferenztmpRef.
4 Setze dienext-Referenz des
”Vorg ¨angersobjekts“ auf die next-Referenz vontmpRef.
5 L ¨osche das durchtmpPtrreferenzierte Objekt mitdelete(in JAVA nicht notwendig).
Ablauf der Remove-Operation (I)
3 7 12
vorgnger
17
NULL head
Schritt 1
3 7 12
head
vorgnger
NULL 17
Schritt 2
12 7
3
vorgnger Schritt 3
head
tmp
17
NULL
Ablauf der Remove-Operation (I)
3 7 12
vorgnger
17
NULL head
Schritt 1
3 7 12
head
vorgnger
NULL 17
Schritt 2
12 7
3
vorgnger Schritt 3
head
tmp
17
NULL
Ablauf der Remove-Operation (I)
3 7 12
vorgnger
17
NULL head
Schritt 1
3 7 12
head
vorgnger
NULL 17
Schritt 2
12 7
3
vorgnger Schritt 3
head
tmp
17
NULL
Ablauf der Remove-Operation (II)
3 Schritt 4
head
tmp
17
NULL
7 12
NULL
3 7
Schritt 5
head
17
Ablauf der Remove-Operation (II)
3 Schritt 4
head
tmp
17
NULL
7 12
NULL
3 7
Schritt 5
head
17
Die Insert-Operation
Es sollinsert(9)simuliert werden:
1 Neuen Node erzeugen (mitnew) und Daten in diesem speichern.
2
”Vorg ¨anger“ auf den Anfang der Liste setzen.
3
”Vorg ¨anger“ solange vorr ¨ucken, bis er auf das Objekt deutet, nach dem das neue Objekt einsortiert werden soll.
4 next-Referenz vontmpRefauf den Nachfolger des Vorg ¨angerobjekts zeigen lassen.
5 next-Referenz des Vorg ¨angerobjekts auf das im ersten Schritt erzeugte Objekt deuten lassenvorgaenger.next = tmpRef;.
Wir erhalten:
NULL
3 7 9 17
head
Ablauf der Insert-Operation (I)
3 17
NULL Schritt 1
head
tmpRef
7 9
vorgaenger
3 7 9
head Schritt 2
17
NULL
tmpRef
tmpRef NULL 17
3
head Schritt 3
7 9
vorgaenger
Ablauf der Insert-Operation (I)
3 17
NULL Schritt 1
head
tmpRef
7 9
vorgaenger
3 7 9
head Schritt 2
17
NULL
tmpRef
tmpRef NULL 17
3
head Schritt 3
7 9
vorgaenger
Ablauf der Insert-Operation (I)
3 17
NULL Schritt 1
head
tmpRef
7 9
vorgaenger
3 7 9
head Schritt 2
17
NULL
tmpRef
tmpRef NULL 17
3
head Schritt 3
7 9
vorgaenger
Ablauf der Insert-Operation (II)
vorgaenger
9 3
Schritt 4
head
tmpRef
NULL 17 7
3 7
9 head
Schritt 5
17 NULL
tmpRef vorgaenger
Ablauf der Insert-Operation (II)
vorgaenger
9 3
Schritt 4
head
tmpRef
NULL 17 7
3 7
9 head
Schritt 5
17 NULL
tmpRef vorgaenger
Einige Bemerkungen
Die oben beschriebenen Operationen funktionieren nur auf dem
”inneren“ Teil der Liste.
Sind Kopf oder Schwanz betroffen, so m ¨ussen diese als Sonderf ¨alle ber ¨ucksichtigt werden. (⇒fehleranf ¨allig & arbeitsintensiv)
Idee: F ¨uge ein
”kleinstes“ und ein
”gr ¨oßtes“ Dummyelement ein (mit ung ¨ultigen Daten).
NULL head
3 7 12 17
−1 9999
gültiger Datenbereich 1 .. 1000
Sentinel
Diese Dummyelemente nennt man auchSentinels. (engl. W ¨achter)
Einige Bemerkungen
Die oben beschriebenen Operationen funktionieren nur auf dem
”inneren“ Teil der Liste.
Sind Kopf oder Schwanz betroffen, so m ¨ussen diese als Sonderf ¨alle ber ¨ucksichtigt werden. (⇒fehleranf ¨allig & arbeitsintensiv)
Idee: F ¨uge ein
”kleinstes“ und ein
”gr ¨oßtes“ Dummyelement ein (mit ung ¨ultigen Daten).
NULL head
3 7 12 17
−1 9999
gültiger Datenbereich 1 .. 1000
Sentinel
Diese Dummyelemente nennt man auchSentinels. (engl. W ¨achter)
Einige Bemerkungen
Die oben beschriebenen Operationen funktionieren nur auf dem
”inneren“ Teil der Liste.
Sind Kopf oder Schwanz betroffen, so m ¨ussen diese als Sonderf ¨alle ber ¨ucksichtigt werden. (⇒fehleranf ¨allig & arbeitsintensiv)
Idee: F ¨uge ein
”kleinstes“ und ein
”gr ¨oßtes“ Dummyelement ein (mit ung ¨ultigen Daten).
NULL head
3 7 12 17
−1 9999
gültiger Datenbereich 1 .. 1000
Sentinel
Diese Dummyelemente nennt man auchSentinels. (engl. W ¨achter)
Einige Bemerkungen
Die oben beschriebenen Operationen funktionieren nur auf dem
”inneren“ Teil der Liste.
Sind Kopf oder Schwanz betroffen, so m ¨ussen diese als Sonderf ¨alle ber ¨ucksichtigt werden. (⇒fehleranf ¨allig & arbeitsintensiv)
Idee: F ¨uge ein
”kleinstes“ und ein
”gr ¨oßtes“ Dummyelement ein (mit ung ¨ultigen Daten).
NULL head
3 7 12 17
−1 9999
gültiger Datenbereich 1 .. 1000
Sentinel
Diese Dummyelemente nennt man auchSentinels.
(engl. W ¨achter)
Einige Bemerkungen
Die oben beschriebenen Operationen funktionieren nur auf dem
”inneren“ Teil der Liste.
Sind Kopf oder Schwanz betroffen, so m ¨ussen diese als Sonderf ¨alle ber ¨ucksichtigt werden. (⇒fehleranf ¨allig & arbeitsintensiv)
Idee: F ¨uge ein
”kleinstes“ und ein
”gr ¨oßtes“ Dummyelement ein (mit ung ¨ultigen Daten).
NULL head
3 7 12 17
−1 9999
gültiger Datenbereich 1 .. 1000
Sentinel
Diese Dummyelemente nennt man auchSentinels. (engl. W ¨achter)
Laufzeiten
F ¨ur die Zeitkomplexit ¨at der Operationen auf Listen mitnElementen ergibt sich:
Operation Zeitkomplexit ¨at
insert O(n) remove O(n) is empty O(1)
Anwendungen von Listen:
Verwaltung von sortierten Dateien
Implementierungsgrundlage f ¨ur Stacks und Queues
Laufzeiten
F ¨ur die Zeitkomplexit ¨at der Operationen auf Listen mitnElementen ergibt sich:
Operation Zeitkomplexit ¨at insert O(n)
remove O(n) is empty O(1)
Anwendungen von Listen:
Verwaltung von sortierten Dateien
Implementierungsgrundlage f ¨ur Stacks und Queues
Laufzeiten
F ¨ur die Zeitkomplexit ¨at der Operationen auf Listen mitnElementen ergibt sich:
Operation Zeitkomplexit ¨at insert O(n)
remove O(n)
is empty O(1)
Anwendungen von Listen:
Verwaltung von sortierten Dateien
Implementierungsgrundlage f ¨ur Stacks und Queues
Laufzeiten
F ¨ur die Zeitkomplexit ¨at der Operationen auf Listen mitnElementen ergibt sich:
Operation Zeitkomplexit ¨at insert O(n)
remove O(n) is empty O(1)
Anwendungen von Listen:
Verwaltung von sortierten Dateien
Implementierungsgrundlage f ¨ur Stacks und Queues
Weitere lineare Datenstrukturen
Man kann eine lineare Liste auch in eine Ringliste umwandeln:
head
3 7 12 17
Anwendungen:
Zuteilung von Zeitscheiben in einem Betriebssystem Sende- und Empfangsbuffer bei der Datenkommunikation
Nachteil linearer Listen: man kann sich nur ineine Richtung bewegen L ¨osung: Verkettungen in zwei Richtungen
NULL head
NULL
Weitere lineare Datenstrukturen
Man kann eine lineare Liste auch in eine Ringliste umwandeln:
head
3 7 12 17
Anwendungen:
Zuteilung von Zeitscheiben in einem Betriebssystem Sende- und Empfangsbuffer bei der Datenkommunikation
Nachteil linearer Listen: man kann sich nur ineine Richtung bewegen L ¨osung: Verkettungen in zwei Richtungen
NULL head
NULL
Weitere lineare Datenstrukturen
Man kann eine lineare Liste auch in eine Ringliste umwandeln:
head
3 7 12 17
Anwendungen:
Zuteilung von Zeitscheiben in einem Betriebssystem Sende- und Empfangsbuffer bei der Datenkommunikation
Nachteil linearer Listen: man kann sich nur ineine Richtung bewegen L ¨osung: Verkettungen in zwei Richtungen
NULL head
NULL
Weitere lineare Datenstrukturen
Man kann eine lineare Liste auch in eine Ringliste umwandeln:
head
3 7 12 17
Anwendungen:
Zuteilung von Zeitscheiben in einem Betriebssystem Sende- und Empfangsbuffer bei der Datenkommunikation
Nachteil linearer Listen: man kann sich nur ineine Richtung bewegen
L ¨osung: Verkettungen in zwei Richtungen
NULL head
NULL
Weitere lineare Datenstrukturen
Man kann eine lineare Liste auch in eine Ringliste umwandeln:
head
3 7 12 17
Anwendungen:
Zuteilung von Zeitscheiben in einem Betriebssystem Sende- und Empfangsbuffer bei der Datenkommunikation
Nachteil linearer Listen: man kann sich nur ineine Richtung bewegen L ¨osung: Verkettungen in zwei Richtungen
NULL head
NULL
Mischen von statischen und dynamischen Ans ¨atzen
Aufgabe: Speichere und verwalte große Datens ¨atze (z.B. vollst ¨andige Personaldatens ¨atze)
L ¨osung 1: Arbeiten mit (dynamischen) Arrays:
Vorteil: schneller Zugriff auf die einzelnen Komponenten
Nachteil: z.B. sind Sortieroperationen sehr aufw ¨andig (kopieren)
L ¨osung 2: Mischansatz:
Den eigentlichen Datensatz in einem dynamisch erzeugten Objekt ablegen
Einen Schl ¨ussel (z.B. Personalnummer) mit einer Referenz auf das Objekt in einem Array ablegen.
Vorteil: Schnelle Zugriffe auf die Daten und effizientes Sortieren Nachteil: Kompliziertere Implementierung
Mischen von statischen und dynamischen Ans ¨atzen
Aufgabe: Speichere und verwalte große Datens ¨atze (z.B. vollst ¨andige Personaldatens ¨atze)
L ¨osung 1: Arbeiten mit (dynamischen) Arrays:
Vorteil: schneller Zugriff auf die einzelnen Komponenten
Nachteil: z.B. sind Sortieroperationen sehr aufw ¨andig (kopieren) L ¨osung 2: Mischansatz:
Den eigentlichen Datensatz in einem dynamisch erzeugten Objekt ablegen
Einen Schl ¨ussel (z.B. Personalnummer) mit einer Referenz auf das Objekt in einem Array ablegen.
Vorteil: Schnelle Zugriffe auf die Daten und effizientes Sortieren Nachteil: Kompliziertere Implementierung
B ¨aume
B ¨aume - Grundlagen
Definition
Das Paar(V,E)mitE ⊆V ×V ist einBaum, wobeiV die (endliche) Menge derKnotenundE die Menge dergerichteten Kantenzwischen den Knoten ist, wenn
es gibt einen ausgezeichneten Knotenw, dieWurzel, und
jeder Knotenk (auchKindvonv genannt), der nicht die Wurzel ist, ist genau miteinerKante mit seinemVaterknotenv verbunden. Ist die Anzahl der Kinder jedes Knotens≤n, dann spricht man von einemn-n ¨aren Baum. Ein 2-n ¨arer Baum heißtBin ¨arbaum.
Ein Knoten ohne Kinder heißtBlatt, sonstinnerer Knoten. Zwischen jedem Knoten und der Wurzel gibt es einenPfad. Die Anzahl der Kanten eines Pfads heißtL ¨angeund die Anzahl der Knoten im l ¨angsten Pfad heißtH ¨ohe(des Baums).