Abstrakte Datentypen

Werbung
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Datenstrukturen 1
Ferd van Odenhoven
Fontys Hogeschool voor Techniek en Logistiek Venlo
Software Engineering
22. September 2014
ODE/FHTBM
Datenstrukturen 1
22. September 2014
1/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Elementare Datenstrukturen
Organisation der Daten
Wahle einer geeignete Datenstruktur
Die vorgeschriebene Operationen führen zu Algorithmen
unterschiedlicher Effizienz
Auswahl von Datenstruktur und effizienz der Algorithmen sind
eng verknüpft.
Eine Datenstruktur ist nicht immer eine passive Größe
Ein Array ist fix, währenddessen eine Liste flexibeler ist.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
2/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Was sind elementare Datenstrukturen?
Bausteine
Einfach strukurierte Datentypen
Arrays (Matrizen)
Listen
Einfach verkettete Listen, darunter:
Speicherplatz-Zuweisung für Listen
Grundlagen der Listenverarbeitung
Doppelt verkettete Liste
zirkuläre Liste
Skip lists
[Zeichenketten]
ODE/FHTBM
Datenstrukturen 1
22. September 2014
3/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Bausteine
Betrachten Sie die primären Konstrukte auf unterer Ebene
für die Speicherung und Verarbeitung in Java
Alle Daten, die wir auf einem Computer verarbeiten, werden
in einzelne Bits zerlegt.
Mit dem Typ können wir spezifizieren, wie man bestimmte
Bit-Mengen verwenden kann.
Mit Methoden können wir spezifizieren, welche Operationen
wir auf den Daten durchführen wollen.
Wir benutzen Java-Klassen
um die Daten zu beschreiben, die wir verarbeiten,
um die Methoden für die Verarbeitung zu definieren, und
um Objekte zu erzeugen, die dann die Information enthalten.
Unsere Datenstrukturen bestehen aus Objekten und Verweisen
auf Objekte.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
4/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Bausteine
Programmierumgebungen müssen eine eingebaute
Unterstützung für grundlegende Bausteine und ihre
Beschreibungen bieten:
Zahlen und Zeichen.
Eingebaute Basisdatentypen: (in Java)
Boolesche Werte (boolean)
Zeichen (char)
8-bit ganze Zahlen (byte)
16-bit ganze Zahlen (short)
32-bit ganze Zahlen (integer)
64-bit ganze Zahlen (long)
32-bit Gleitkomma-Zahlen (float)
64-bit Gleitkomma-Zahlen (double)
ODE/FHTBM
Datenstrukturen 1
22. September 2014
5/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Bausteine
In Java werden diese Basisdatentypen primitive Typen
genant und heißen:
boolean, char, byte, short, int, long, float, double.
In generischer Terminologie heißen diese Standardtypen oft
integer (ganze Zahlen), floating-point und character: deren
Bereich ist begrenzt.
Der Typ boolean enthält die logischen Werte true oder
false.
Gleitkomma-Zahlen sind näherungsweise reelle Zahlen.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
6/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Quiz
Puzzler: double d = ?; boolean b = (d==d+1);
Question: Für welchen Wert(e) von d kann b gleich true
sein?
ODE/FHTBM
Datenstrukturen 1
22. September 2014
7/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Datentyp
(Def. 3.1) Ein Datentyp ist: eine Wertemenge und eine
Sammlung von Operationen auf diesen Werten.
Operationen sind mit Typen assoziiert (nicht umgekehrt).
Wenn wir eine Operation durchführen, müssen wir
sicherstellen, dass sowohl die Operanden als auch das Ergebnis
den richtigen Typ haben.
Java führt implizite (primitive) Typ-Konvertierungen aus;
in sonstige Fällen wenden wir Casts (Umwandlungen) an, also
explizite Typ-Konvertierungen; beispielsweise ((float) x /N),
wenn x und N ganze Zahlen sind.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
8/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Datentyp
Wo gibt es Datentypen? - ÜBERALL!
Viele Operationen, die mit Standarddatentypen assoziiert sind
(wie die arithmetischen Operationen), sind in Java eingebaut.
Andere Operationen kommen als Methoden vor, die in
Standard-Java-Bibliotheken definiert sind; weitere gibt es in
den Java-Methoden, die wir in unserem Programm definieren.
Beachten Sie: Wenn wir eine einfache Methode in Java
definieren, erzeugen wir einen Datentyp. Die durch die
Methode implementierte Operation wird für einen solchen
Datentypen definiert.
Die Datentypen werden durch die Parameter repräsentiert.
Daraus folgt, dass jedes Java-Programm ein Datentyp ist,
bestehend aus Wertenmengen und denen mit ihnen
assozierten Methode.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
9/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Bausteine
Datentyp
Zusammenfassung - Java-Programmierung
Wir haben vorwiegend einzelne Teile diskutiert, die wie
Bausteine auf Basisdatentypen angewendet werden.
Oft arbeiten wir mit riesigen Datenmengen und setzen für
diesen Zweck Basismethoden ein.
Den Begriff Datenstruktur benutzen wir für einen
Mechanismus zur Organisation von Information, der bequeme
und effiziente Mechanismen für Zugriff und Bearbeitung bietet.
Viele wichtige Datenstrukturen basieren auf der einen oder
beiden der zwei grundlegenden Herangehensweisen in
Arrays: Wir organisieren die Objekte in einer linearen
Reihenfolge mit fester Länge.
Listen: Wir organisieren die Objekte auf eine Art ohne
festgelegte Länge, die besser für die Bearbeitung geeignet sein
könnte.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
10/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Zur Anwendung abstrakter Datentypen (ADTs)
Ein ADT definiert ein Typ (Name) und die dazugehörige
Methoden
Ein ADT legt keine Datenstruktur fest
ADT ist das Grundlagende Konzept der objekt-orientierten
Programmierung.
Ein ADT ist das Java Interface ähnlich, aber enthält auch
Konstruktoren.
Eine ADT ist in wesen eine API für 1 Typ!
ODE/FHTBM
Datenstrukturen 1
22. September 2014
11/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Jaa und Abstrakte Datentypen
Wie unterstützt Java das Bedürfnis nach ein ADT?
Eine Schnittstelle, die die zu verwendenden Methoden
deklariert. Die Methoden sind public. Die Schnittstelle kann
sowohl public als package-private sein.
Eine Implementierung aller Methoden in der Schnittstelle.
Ein Client-Programm, das die public Methoden in der public
Schnittstelle benutzt, um auf einer höherer Abstraktionsebene
arbeiten zu können.
Ein Client-Programm-Teil, das die public Methoden in der
package private Schnittstelle benutzt.
Frage: warum ist ein Konstruktor niemals Teil einer Java
Schnittstelle?
ODE/FHTBM
Datenstrukturen 1
22. September 2014
12/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Zur Anwendung von ADTs
Wir müssen die (abstrakten) Objekte definieren, die wir
manipulieren wollen, und die Operationen, die wir auf ihnen
durchführen wollen.
Wir müssen die Daten in einer Datenstruktur repräsentieren
und die Operationen implementieren.
Wir wollen sicherstellen, dass die Objekte zum Realisieren
einer Anwendung leicht anwendbar sind.
Wir wollen den Client von der Implementierung trennen und
so erreichen, dass viele Clients eine einfache Implementierung
nutzen können, ohne dass wir Code ändern müssen.
Wir müssen uns der Kosten von Basisoperationen bewusst
sein, (siehe 2. Vorlesung). Diese Kosten zu kalkulieren, ist auf
abstrakterer Ebene oft einfacher als durch die genaue
Betrachtung einer konkreten Implementierung.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
13/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Abstrakter Datentyp (Definition 4.1)
ADT: Definition 4.1
Ein abstrakter Datentyp (ADT) ist ein Datentyp (eine Menge von
Werten und eine Sammlung von Operationen auf diesen Werten),
auf den nur durch eine Schnittstelle zugegriffen wird.
Ein Programm, das einen ADT benutzt, bezeichnen wir als Client,
und ein Programm, das den Datentyp spezifiziert, als eine
Implementierung.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
14/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Eine Punkt-Klasse Implementierung
class Point {
private double x , y ;
Point () {
x = Math . random ();
y = Math . random ();
}
Point ( double x , double y ) {
this . x = x ; this . y = y ;
}
Weiter auf folgende Folie.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
15/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Eine Punkt-Klasse Implementierung 2
(Fortsetzung )
double x () { return x ; }
double y () { return y ; }
double r () { return Math . sqrt ( x * x + y * y ); }
double theta () { return Math . atan2 (y , x ); }
double distance ( Point p ) {
double dx = this . x () - p . x ();
double dy = this . y () - p . y ();
return Math . sqrt ( dx * dx + dy * dy );
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
16/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Punkt-Klasse Implementierung 3
Erste Implementierung - Was ist wichtig?
Diese Klasse enthält 8 Methoden
2 Konstruktoren
2 Zugriffsmethoden, die Werte der Datenfelder zurückgeben,
2 Methoden für die Umwandlung in Polarkoordinaten,
1 Methode für die Berechnung der Entfernung zu einem
anderen Punkt, und
Die Daten-Repräsentation ist private und direkter Zugriff
oder Änderung ist nur durch Methoden der Klasse selber
möglich. Die public-Methoden können dagegen durch jeden
Client genutzt werden.
Wenn wir verhindern, dass Clients direkt auf die
Daten-Repräsentation zugreifen, können wir sie ändern!
ODE/FHTBM
Datenstrukturen 1
22. September 2014
17/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Punkt-Klasse: Zweite Implementierung 1
class Point {
private double r , theta ;
Point () {
double x = Math . random ();
double y = Math . random ();
this = new Point (x , y );
}
Point ( double x , double y ) {
r = Math . sqrt ( x * x ; y * y );
theta = Math . atan2 (y , x );
}
Weiter auf folgende Folie.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
18/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Punkt-Klasse: Zweite Implementierung 2
(Fortsetzung )
double r () { return r ; }
double theta { return theta ; }
double x () { return r * Math . cos ( theta ); }
double y () { return r * Math . sin ( theta ); }
double distance ( Point p ) {
double dx = x () - p . x ();
double dy = y () - p . y ();
return Math . sqrt ( dx * dx + dy * dy );
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
19/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Wie leiten Sie eine Schnittstelle ab?
Eine Schnittstellendefinition leiten Sie von einer
Klassendefinition ab durch löschen:
aller private Elemente,
die Implementierungen der public Methoden sowie die
Parameternamen, so dass nur die Signatur der public
Methoden übrig bleibt.
Wenn Sie das für zwei beliebige Klassen tun, die eine
Schnittstelle implementieren, sollte die selbe Schnittstelle
dabei herauskommen.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
20/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Punkt-Klasse ADT
ADT Point // ADT interface
{
Point ()
Point ( double , double )
double x ()
double y ()
double r ()
double theta ()
double distance ( Point )
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
21/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Point Schnittstelle in Java
interface Point // Java interface
{
// constructors are not allowed !
double x ();
double y ();
double r ();
double theta ();
double distance ( Point );
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
22/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Welchen Bezug hat die Schnittstelle zu ADTs?
Implementierungen der Klasse Datentyp, wie die
Implementierungen von Point durch kartesische Koordinaten
oder Polarkoordinaten, werden manchmal konkrete
Datentypen genannt.
Aus unserer ADT Perspektive implementieren die genannten
Klassen aber den selben Datentyp - Point - mit
unterschiedlichen Daten-Repräsentationen; denn die Klassen
bedienen die selben Methoden, die die selben Signaturen
haben.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
23/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Einführung
Abstrakte Datentypen (ADTs)
Klasse Point Beispiel
Zusammenfassung: Schnittstellen und ADTs gelernt?
Die Signaturen der Methoden sind in einer
Klasse nicht private.
Elemente einer Klasse, die nicht Teil ihrer
Schnittstelle sind, sind private!
Wir untersuchen die Schnittstellen, bevor wir die
Implementierungen betrachten!
ODE/FHTBM
Datenstrukturen 1
22. September 2014
24/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Arrays
Arrays
Arrays werden benutzt um alle möglichen Objekttypen zu
organisieren.
Wir können Arrays als primitiven Typ oder Klasse deklarieren,
aber danach nicht mehr vom Typ ändern.
Arrays definieren eine endliche sequentielle Ordnung der
Elemente.
Die Elemente in einem Array von n Elemente können über
einen Index im Bereich von 0 bis n-1 erreicht werden.
Die Zeit die es kostet ein Item zu finden ist unabhängig vom
Wert des Index.
Notation: Elemente eines Arrays a sind
a[0], a[1], a[2], a[3], . . .
ODE/FHTBM
Datenstrukturen 1
22. September 2014
25/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Arrays
Eine der wichtigsten elementaren Datenstrukturen
Ein Array ist eine feste Sammlung von Daten des gleichen
Typs, die zusammenhängend gespeichert werden und auf die
durch einen Index zugegriffen wird.
Das i-te Element eines Array wird als a[i] bezeichnet.
In Java müssen Sie als Programmierer selbst darauf achten,
dass Sie Indizes benutzen, die nicht negativ sind und kleiner
als die Größe des Arrays.
Arrays hängen auf praktisch allen Rechnern direkt von der
Hauptspeichergröße ab.
Sie können sich den gesamten Hauptspeicher als Array
vorstellen (Speicheradressen entsprechen den Indizes).
Wir können davon ausgehen, dass ein Array-Zugriff wie a[i]
in einige wenige Maschinenanweisungen übersetzt wird.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
26/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Beispiel: Das Sieb des Eratosthenes
Finde Primzahlen die kleiner als eine gegebene ganze Zahl.
Wir nehmen ein boolean Array bei dem alle a[i] auf true
gesetzt sind. Wenn i Primzahl ist wird a[i] auf true
gesetzt, sonst auf false.
Dann fangen wir an beim letzten Priemzahl Index im Bereich
vom Beginn des Arrays, worin alle Priemzahlen bekannt sind.
Anschließend werden alle Array-Elemente auf false gesetzt, die
Indizes entsprechen, die ein Vielfach dieses Primzahl sind.
Jede nächsten Durchgang, wenn notwendig, startet beim
letztes Priemzahl in die Reihe von bekannte Priemzahlen vom
Anfang des Arrays.
Begründe die Tatsache das man fertig ist wenn der Index
gleich die Wurzel der Länge des Arrays ist.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
27/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Beispiel: Das Sieb des Eratosthenes
Dieser Algorithmus wird oft in unterlegten Graphenstrukturen
in Netzen eingesetzt, Siehe das Buch.
Es gibt viele effizientere Implementierungen für diese
Methode, Siehe das Buch.
Dennoch zeigt diese Implementierung, wie wir uns eine
Datenstruktur zu nutzen machen können, ein erstes
Berechnungsverfahren zu finden. Denken Sie daran es ist
immer ein Wechselspiel zwischen Operationen auf
Datenstructuren und umgekehrt.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
28/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Beispiel: Das Sieb des Eratosthenes
class Primes {
public static void main ( String [] args ) {
int N = integer . parseInt ( args [0]);
boolean [] a = new boolean [ N ];
for ( int i = 2; i < N ; i ++) a [ i ] = true ;
for ( int i = 2; i < N ; i ++)
if ( a [ i ] != false )
for ( int j = i , i * j < N ; j ++)
a [ i * j ] = false ;
for ( int i = 2; i < N ; i ++ )
if ( i > N - 100 )
if ( a [ i ]) System . out . println ( " " + i );
System . out . println ();
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
29/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Arrays
Beispiel: Das Sieb des Eratosthenes
Das Sieb des Eratosthenes
Für die Berechnung aller Primzahlen kleiner als 32
werden a[0] und a[1] nicht benutzt (und nicht angezeigt)
0:
1:
2:
3:
a:
0:
1:
2:
3:
a:
ODE/FHTBM
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
T T T T T T T T T T T T T T T T T T T
F
F
F
F
F
F
F
F
F
F
F
T T F T F T F F F
21 22 23 24 25
T T T T T
F
F
F
F
F F T F F
T
F
T
F
F
F
T
F
T
F
26 27 28 29 30 31
T T T T T T
F
F
F
F
F
F
F
Datenstrukturen 1
T
F
T
22. September 2014
30/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Verkettete Listen
Verkettete Listen
Lineare Struktur: jedes Listelement verweist auf das nächste
Listelement!
Einfache Operationen, wie insert (einfügen) und remove
(entfernen)
Konventionen zu Listenkopf und –ende in verketteten Listen
wichtigste Basisoperationen
Einfügen eines Listenelements (List item insertion)
Löschen eines Listenelements (List element deletion)
Elementare Listenverarbeitung - einige wichtige Operationen
List reversal (Listenumkehrung) und list traversal
(Traversierung von Listen)
List insertion sort (Sortieren durch Einfügen)
Klasse zirkuläre Listen
Skip Lists
Speicherplatz-Zuweisung für Listen (lists can grow, arrays not)
ODE/FHTBM
Datenstrukturen 1
22. September 2014
31/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Verkettete Liste verglichen mit Array
Verkettete Listen und ihre grundlegenden Eigenschaften
verglichen mit Arrays und ihren Anwendungen!
Wichtig: (Verschiedene Formen des) Zugriffs auf sequenziell
organisierte Elemente
Traversierung versus Index in Arrays: Objekt refenzierung
Operationen: zB. Sortierung von Elementen (oder Items) in
beiden Datenstrukturen?
Performanz Themen
Spezifischer Listentypen: zirkuläre Liste, skip list
System- und Implementierungs-spezifische Entscheidungen
Konventionen zu Listenkopf und -ende in verketteten Listen:
pros & cons
Charakteristika der Speicherplatz-Zuweisung
ODE/FHTBM
Datenstrukturen 1
22. September 2014
32/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Datenstrukturen verkettete Liste & Array
Eine Sache soll klar sein:
Eine verkettete Liste als Datenstruktur und eine allgemeine
verkettet Liste Klasse sind zwei unterschiedliche Sachen!
Als Datenstruktur ist eine verkettete Liste kurz und
einfach, zum Beispiel gibt es keine getters und setters.
Der einzigen Grund für seine Existenz ist das Sie
gebraucht wird innerhalb einen Algorithmus.
Eine allgemein anwendbare verkettete Liste ist groß
(Code), komplex und robust; Sie soll in alle mögliche
und unbekannte Umgebungen funktionieren.
Vergleichen Sie mal das einfache Array mit der Java
ArrayList, die letzte versucht sogar eine Liste zu sein!
ODE/FHTBM
Datenstrukturen 1
22. September 2014
33/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Einfache Herangehensweise Implementierungen
verketteter Listen
Stellen Sie sich verkettete Listen als Implementierungen
einer Reihe von Element-(oder Item-)Mengen vor
die an einem bestimmten Knoten (node) beginnen,
dessen Element wir als erstes in der Folge betrachten.
Verfolgen Sie seinen Zeiger auf einen anderen Knoten, womit
Sie ein Element (oder Item) erreichen, das wir als zweites in
der Folge betrachten,
und so weiter.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
34/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
(Eine erste) Definition einer verketteten Liste
Def 3.2 Eine verkettete Liste ist eine Menge von Elementen (oder
Items), bei der jedes Element (oder Item) Teil eines Knotens
ist, der auch einen Zeiger auf einen Knoten enthält.
null
Item
ODE/FHTBM
Item
Datenstrukturen 1
Item
22. September 2014
35/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Konventionen für den Endknoten in verketteten Listen
Einfache Implementierungen von sequenziellen
Elementanordnungen, die eine der folgenden
Konventionen für den Zeiger im Endknoten
einhalten, auch bekannt unter den Namen:
Tail-Referenz.
Es ist ein Nullzeiger, der auf keinen Knoten zeigt.
Er weist auf einen Dummy-Knoten, der kein Element
enthält.
Er weist zurück auf den ersten Knoten, so dass eine
zirkuläre Liste (circular oder cyclic list) entsteht.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
36/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Konventionen für den Endknoten in verketteten Listen
A
null
Item
Item
Item
B
null
Item
Item
dummy
C
Item
ODE/FHTBM
Item
Datenstrukturen 1
Item
22. September 2014
37/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Erstellen von verlinkbaren Objekten
Folgendermaßen benutzen wir Objekte als Knoten und
Verweise auf Objekte als Zeiger:
class Node { Object item; Node next;}
Wir implementieren also die Knoten in verketteten Listen als
Objekte vom Typ Node.
Node besteht aus einem Element (dessen Typ hier unwichtig
ist) und einem Verweis auf einen Knoten.
Wir können eine Liste also mit diesem Kode definieren:
class Node < Item > {
Item item ; Node < Item > next ;
Node ( Item v ) {
item = v ; next = null ;
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
38/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Java - Löschen in einer verketteten Liste
Node-Referenz x zeigt zu dem Node der eine next-Referenz
hat, die auf den Node zeigt die man lösschen möchte.
Um den Knoten nach Knoten x zu löschen, verwenden wir die
Anweisungen
t = x.next; x.next = t.next;
oder einfach
x.next = x.next.next;
ODE/FHTBM
Datenstrukturen 1
22. September 2014
39/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Java - Einfügen in eine verkettete Liste
Um Knoten t an der Stelle nach Knoten x einzufügen,
verwenden wir diese Anweisungen
t.next = x.next; x.next = t;
ODE/FHTBM
Datenstrukturen 1
22. September 2014
40/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Elementare Listenverarbeitung
Verkettete Listen als Datenstrukturen, die einfacher neu zu
ordnen sind
Statt ArrayIndexOutOfBoundsException müssen wir jetzt
die Referenzen in der verkettete Liste überwachen.
Weitere Basisoperationen auf Listen
list traversal (Traversierung von Listen)
hinzufügen und löschen von Elemente
list insertion sort (Sortieren durch Einfügen)
ODE/FHTBM
Datenstrukturen 1
22. September 2014
41/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Elementare Listenverarbeitung
Mit verketteten Listen ist es schwierig direkt auf ein Element
(oder Item) zuzugreifen, aber die Neuordnung ist einfacher als
bei Arrays.
In Listen kommt häufig der Fehler vor, dass ein Verweis auf
kein einziges Element zeigt oder auf mehr als ein Element
(oder Item) zeigt, wobei ein anderes Element verloren geht.
Bestimmte Probleme können wir auch durch Verwendung so
genannter zirkulärer (circular oder cyclic) Listen vereinfachen.
Die wichtigsten Operationen sind das Einfügen oder Löschen
eines Elements (oder Items) in der angegebenen Liste und die
Traversierung einer Liste.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
42/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Definition 2 einer verketteten Liste (wie sie oft
implementiert wird)
Def 3.3 Eine verkettete Liste ist entweder ein Nullzeiger (A), ein
Zeiger auf ein Element (B) oder ein Zeiger auf eine verkettete
Liste (C).
A
null
null
B
Item
C
null
Item
ODE/FHTBM
Datenstrukturen 1
Item
22. September 2014
43/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Liste durchlaufen (im Vergleich zur Array-Verarbeitung)
Wir implementieren eine Methode zur Traversierung einer
Liste.
Wenn x auf den ersten Knoten einer Liste weist, der
Endknoten einen Nullzeiger hat und visit eine Methode ist, der
wir ein Element als Parameter übergeben können, könnten wir
schreiben:
for (Node t = x; t != null; t = t.next)
visit(t.item);
und damit eine Liste traversieren.
Diese Schleife (oder die äquivalente while-Form) ist in
Listenverarbeitungsprogrammen allgegenwärtig, ebenso wie
eine Schleife dieser Art:
for (int i = 0; i < N; i++)
in Array-verarbeitenden Programmen.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
44/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
List reversal (Listenumkehrung)
static Node reverse ( Node list ) {
Node nextTodo , todo = list , revlist = null ;
while ( todo != null ) {
nextTodo = todo . next ;
todo . next = revlist ;
revlist = todo ;
todo = nextTodo ;
}
return revlist ;
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
45/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
List insertion sort: 1
class SortedList {
private int size ;
// Data structure with private inner class Node .
private Node list ;
private class Node {
int val ;
Node next ;
Node ( int v , Node t ) {
val = v ;
next = t ;
}
}
public int size () {
return size ;
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
46/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
List insertion sort: 2
// Contructor initializes data structure
public SortedList () {
list = new Node (0 , null );
size = 0;
}
// insert method that keeps the list sorted .
public void insert ( int value ) {
Node x = list ;
while ( x . next != null && x . next . val < value ) {
x = x . next ;
}
x . next = new Node ( value , x . next );
size ++;
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
47/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
List insertion sort: 3
Zwei praktische Aufgaben!
Implementieren Sie SortedList die Klasse mal wobei ein
Array als Datenstruktur wird eingesetzt.
Schreiben Sie für die gegeben Implementierung eine Methode
mit nachfolgende Signatur:
public int[] getValues()
wobei die Werte in der gleichen Reihenordnung stehen als in
der sortierte Liste.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
48/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Listenkopf & -ende Konventionen in verketteten Listen
circular, never empty (zirkuläre Liste, nie leer)
Häufigste Herangehensweise: Verkettete Liste mit Verweis auf
den Listenkopf und leerem Ende (Null Tail)
Verkettete Liste mit Dummy-Kopf und leerem Ende
Verkettete Liste mit Dummy-Kopf und Endknoten
ODE/FHTBM
Datenstrukturen 1
22. September 2014
49/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Kopf & Ende Konventionen: Zirkuläre Listen
Zirkuläre, nie leere Liste
erstes Einfügen: head.next = head;
t nach x einfügen: (t and x are Node references, t is a new Node)
t.next = x.next; x.next = t;
nach x löschen: x.next = x.next.next;
Schleife durchlaufen:
t = head;
do {... t = t.next;} while (t !=head);
testen, ob ein Element: head.next == head
ODE/FHTBM
Datenstrukturen 1
22. September 2014
50/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Kopf & Ende Konventionen: null tail
Verweis auf Listenkopf, leeres Ende
initialisieren: head = null;
t nach x einfügen: (t and x are Node references, t is a new Node)
if(x == null) { head = t; head.next = null;}
else {t.next = x.next; x.next = t;}
nach x löschen: t = x.next; x.next = t.next;
Schleife durchlaufen:
for (t = head; t != null; t = t.next)
testen, ob leer: head == null
ODE/FHTBM
Datenstrukturen 1
22. September 2014
51/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Kopf & Ende Konventionen: dummy head and null tail
Dummy-Kopf und Endknoten
initialisieren: head = new Node(); head.next = null;
t nach x einfügen: (t and x are Node references, t is a new Node)
t.next = x.next; x.next = t;
nach x löschen: t = x.next; x.next = t.next;
Schleifendurchlauf:
for (t = head.next; t != null; t = t.next)
testen, ob leer: head.next == null
ODE/FHTBM
Datenstrukturen 1
22. September 2014
52/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Kopf & Ende Konventionen: dummy head and tail
Dummy-Kopf und Dummy Endknoten
initialisieren:
head = new Node(); tail = new Node();
head.next = tail; tail.next = tail;
t nach x einfügen: t.next = x.next; x.next = t;
nach x löschen: x.next = x.next.next;
Schleife: (t and x are Node references, t is a new Node)
for (x = head.next; x != tail; x = x.next)
testen, ob leer: head.next == tail
ODE/FHTBM
Datenstrukturen 1
22. September 2014
53/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Verkettete zirkuläre Listen Circular (cyclic linked lists)
Das Josephus Problem, siehe auch:
Exercise 1.3.37 on page 168 of the book.
Direkte Implementierung durch eine zirkuläre Liste
Implementierung durch eine generalisierte zirkuläre Liste
Vorteile von Implementierungen mit Client-Schnittstelle
ODE/FHTBM
Datenstrukturen 1
22. September 2014
54/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
2
1
2
1
9
9
3
3
8
4
8
4
7
5
7
6
6
Beispiel: jede fünfte wird selektiert
ODE/FHTBM
Datenstrukturen 1
22. September 2014
55/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
2
2
9
9
3
3
8
4
8
4
7
6
6
Beispiel: jede fünfte wird selektiert
ODE/FHTBM
Datenstrukturen 1
22. September 2014
56/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
2
2
9
9
3
8
6
8
6
Beispiel: jede fünfte wird selektiert
ODE/FHTBM
Datenstrukturen 1
22. September 2014
57/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
2
2
9
8
8
Beispiel: jede fünfte wird selektiert
ODE/FHTBM
Datenstrukturen 1
22. September 2014
58/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
Beim Josephus Problem geht es
darum, eine Führungsperson
auszuwählen.
8
Die Identität der gewählten
Person ist eine Funktion von
N(= 9) und M(= 5).
Im angegebenen Beispiel wird
diese Folge von Knoten
aussortiert
5 1 7 4 3 6 9 2
ODE/FHTBM
Datenstrukturen 1
22. September 2014
59/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
class Josephus {
static class Node {
int val ; Node next ;
Node ( int v ) { val = v ; }
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
60/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem
public static void main ( String [] args ) {
int N = integer . parseInt ( args [0]);
int M = integer . parseInt ( args [1]);
Node t = new Node (1);
Node x = t ;
for ( int i = 2; i < N ; i ++)
x = ( x . next = new Node ( i ));
x . next = t ;
while ( x != x . next ) {
for ( int i = 1; i < M ; i ++)
x = x . next ;
x . next = x . next . next ;
}
system . out . println ( " Survivor is " + x . val );
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
61/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Generalisierung – Klasse zirkuläre Listen
class CircularList {
static class Node {
int val ; Node next ;
Node ( int v ) { val = v ; }
}
Node next ( Node x ) {
return x . next ;
}
int val ( Node x ) {
return x . val ;
}
Node insert ( Node x , int v ) {
Node t = new Node ( v );
if ( x == null ) t . next = t ;
else {
t . next = x . next ; x . next = t ;
}
return t ;
}
void remove ( Node x ) {
x . next = x . next . next ;
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
62/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Generalisierung – Klasse zirkuläre Listen
Diese Klasse implementiert Basisoperationen auf zirkulären
Listen.
Sie erlaubt Clients, solche Listen zu bearbeiten und stellt
sicher, dass sie das tun können, ohne sich von den
Implementierungsdetails abhängig zu machen.
Clients können mit insert einen neuen Knoten mit einem
gegebenen Wert nach einem angegebenen Knoten in die Liste
einfügen und mit remove den Knoten löschen, der einem
angegebenen Knoten folgt.
Die Zugriffsmethoden next und val liefern den Clients Werte
von Feldern; mit ihnen haben wir Freiheit der
Implementierung.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
63/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem mit zirkulären Listen
class JosephusY {
public static void main ( String [] args ) {
int n = Integer . parseInt ( args [0]);
int m = Integer . parseInt ( args [1]);
CircularList cl = new CircularList ();
CircularList . Node x = null ;
for ( int i = 1; i <= n ; i ++)
x = cl . insert (x , i );
while ( x != cl . next ( x )) {
for ( int i = 1 , i < m ; i ++)
x = cl . next ( x );
cl . remove ( x );
}
System . out . println ( " Survivor is " + cl . val ( x ));
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
64/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Josephus Problem: generalisierten zirkulären Liste
Dieses Beispiel bietet ein Szenario mit Implementierung einer
Client-Schnittstelle für die zirkuläre Liste.
Diese Implementierung der zirkulären Liste nutzt die selben
Methoden, wir können sie ohne Änderungen am Programm
durchführen.
Wir identifizieren die wichtigen Operationen für die
Berechnung. Wir kapseln sie alle in einer einzigen Klasse, das
hat zwei Vorteile:
Wir können im Client auf einer höheren Abstraktionsebene
arbeiten.
Wir prüfen verschiedene konkrete Implementierungen kritischer
Operationen und testen ihre Effektivität.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
65/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Mögliche Erweiterungen: doppelt verkettete Listen
Indem wir weitere Zeiger hinzufügen, können wir zusätzlich
die Möglichkeit einer Rückwärtsbewegung durch verkettete
Listen schaffen.
Wir können Operationen unterstützen, mit denen es möglich
wird ”das Element vor einem angegebenen Element zu
finden”, indem wir eine Liste mit doppelter Verkettung
nutzen, in der wir für jeden Knoten zwei Zeiger verwenden:
einen (prev) auf das Element davor, und
einen weiteren (next) auf das Element danach.
ODE/FHTBM
Datenstrukturen 1
22. September 2014
66/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Mögliche Erweiterungen: doppelt verkettete Listen 2
Mit Dummy-Knoten oder einer zirkulären Liste können wir
sicherstellen, dass x, x.next.prev, und x.prev.next für
jeden Knoten in der doppelt verketteten Liste gleich sind.
Wir müssen folgende Operationen ändern oder implementieren
remove
insert after,
insert before
ODE/FHTBM
und
in einer doppelt verketteten Liste.
Datenstrukturen 1
22. September 2014
67/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Mögliche Erweiterungen: a Node for a skiplist
private class Node <K ,V > {
K key ;
V val ;
Node <K ,V > below , above , prev , next ;
Node ( K key , V value ) {
this . key = key ;
this . val = value ;
below = null ;
above = null ;
prev = null ;
next = null ;
}
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
68/69
Bausteine
Abstrakte Datentypen
Arrays
Verkettete Listen
Konventionen für Endknote
Elementare Listenverarbeitung
Verkettete zirkuläre Listen
Erweiterungen von der einfach verkettete Liste
Mögliche Erweiterungen: a skiplist interface
public interface SkipList <K ,V > {
int getHeight ();
int getSize ();
void insert ( K key , V value );
boolean isEmpty ();
V removeItem ( K key );
V search ( K key );
}
ODE/FHTBM
Datenstrukturen 1
22. September 2014
69/69
Herunterladen