Liste

Werbung
Induktive
Datenbereiche
Induktive Datenbereiche, Verkettete
Listen, Mutatoren, Operationen,
Konstruktoren, Prädikate, Selektoren,
Bäume, Binärbäume, Bäume mit
Blättern, abstrakte Klassen
Induktiv definierte Daten
„
Die natürlichen Zahlen sind induktiv definiert
…
…
„
0 ist eine natürliche Zahl
Wenn N eine natürliche Zahl ist, dann auch N+1
Binärzahlen kann man induktiv definieren
…
…
…
0 ist eine Binärzahl
1 ist eine Binärzahl
Ist B eine Binärzahl, dann auch
„
„
„
B0, und
B1.
Strings kann man induktiv definieren
…
…
Der leere String “ “ ist ein String
Ist S ein String und z ein Zeichen,
dann ist S . z ein String
„
Ausdrücke wurden bereits induktiv definiert
„
Binärbäume kann man induktiv definieren
…
…
0, |, ||, |||, ||||, |||||, ||||||, ...
Der leere Baum ist ein Binärbaum
Sind B1 und B2 Binärbäume, dann auch
Praktische Informatik I
0, 1,
00, 01, 10, 11,
000, 001, 010, 011,
100, 101, 110, 111
““,
“a“, “b“, ...
“aa“, “ab“, ... , “ba“, “bb“, ...
“aaa“, “aab“, ...
B1
B2
H. Peter Gumm, Philipps-Universität Marburg
Verkettete Listen
„
Listen sind Folgen von Elementen
„
Im Unterschied zu Arrays können Listen beliebig wachsen und
schrumpfen
…
…
„
Verkettete Listen kann man sich wie eine Perlenschnur vorstellen
…
…
„
Neue Elemente werden an die Liste angehängt
Nicht mehr benötigte Elemente können entfernt werden
Von jeder Perle gibt es eine Verbindung zur folgenden
In den Perlen befindet sich die Information
Die Liste besteht aus Zellen.
…
…
Jede Zelle hat einen Inhalt, und
Einen Verweis auf die folgende Zelle
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Die Zelle – unsere Perle
„
Die Liste besteht aus Zellen.
…
…
Jede Zelle hat einen Inhalt,
und
einen Verweis auf die
folgende Zelle
17
inhalt next
Praktische Informatik I
42
inhalt next
101
38
inhalt next
inhalt next
H. Peter Gumm, Philipps-Universität Marburg
Listen: Perlen aufgefädelt
„
Ein Liste besteht aus
einem Link auf die erste Zelle
Methoden um Elemente
…
…
„
„
„
aufzunehmen
zu suchen
zu löschen, etc.
anfang
vorher
nachher
42
inhalt next
neue Zelle
Praktische Informatik I
nachher
101
38
inhalt next
inhalt next
H. Peter Gumm, Philipps-Universität Marburg
Wir bauen uns eine Liste in BlueJ
„
BlueJ zeigt durch einen
gestrichelten Pfeil an, dass
Liste die Klasse Zelle
benutzt.
„
wir erzeugen eine Liste
meineListe
„
und speichern
nacheinander
…
…
…
37
42
81
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Wir inspizieren die Liste
„
uiu
Dies entspricht
81
anfang
Praktische Informatik I
inhalt next
42
inhalt next
37
inhalt next
H. Peter Gumm, Philipps-Universität Marburg
Entfernen eines Elementes
„
Um ein Element einer Liste zu entfernen, verbinden wir
die Vorgängerzelle mit der Nachfolgerzelle
81
anfang
inhalt next
37
42
inhalt next
inhalt next
Zelle v
v.next = v.next.next
„
Das abgeklemmte Element wird irgendwann
automatisch von der Java-Speicherbereinigung
(garbage collection) gefunden und recycled.
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
removeNth – entferne n-tes Element
„
Von der leeren Liste kann
man nichts entfernen
„
Das erste Element hat
keine Vorgängerzelle,
daher müssen wir es
gesondert behandeln
„
Solange
…
…
Zähler n > 1, und
v einen Nachfolger hat
vermindere n und rücke v
eine Zelle weiter.
„
Falls v einen Nachfolger
hat, klemme ihn ab.
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Mutatoren, Operationen
„„
Für
FürMethoden
Methodenzur
zurManipulation
Manipulationvon
von
Daten
Datengibt
gibtes
eszwei
zweiMöglichkeiten
Möglichkeiten
„
„
insert ist ein Mutator
removeNth ist ein Mutator
1.
1. Die
DieMethode
Methodeverändert
verändertdas
dasObjekt
Objekt
Solche
SolcheMethoden
Methodenheißen
heißenMutatoren
Mutatoren
Mutatoren
sind
Kennzeichen
Mutatoren sind Kennzeichendes
des
imperativen
Programmierens
imperativen Programmierens
•• void
voidMethoden
Methodensind
sindimmer
immerMutatoren
Mutatoren
•• Mutatoren
Mutatorensind
sindmanchmal
manchmaleffizienter
effizienter
••
••
2.
2. Die
DieMethode
Methodelässt
lässtdas
dasObjekt
Objekt
unverändert.
Resultat
ist
unverändert. Resultat istneues
neuesObjekt
Objekt
••
••
••
••
Praktische Informatik I
Solche
SolcheMethoden
Methodenheißen
heißenOperationen
Operationen
Operationen
Operationensind
sindKennzeichen
Kennzeichendes
des
deklarativen
Programmierens
deklarativen Programmierens
Mit
MitOperationen
Operationenkann
kannman
manleichter
leichter
umgehen
umgehen
Operationen
Operationensind
sindweniger
wenigerfehleranfällig
fehleranfällig
„
Eine insert
entsprechende Operation
müsste
eine neue Liste
konstruieren und
… die alte unversehrt lassen
…
„
Eine removeNth
entsprechender Operation
müsste
eine neue Liste
konstruieren
… die alte unversehrt lassen
…
„
„
Wie soll das gehen ?
Das soll einfacher sein ?
H. Peter Gumm, Philipps-Universität Marburg
Programmieren mit Operationen
„
Konstruktoren
…
Konstruiert die leere Liste
(anfang = null)
…
Konstruiert eine neue Liste
mit erstem Element n und
Restliste l
neue
Liste
neue
Zelle
anfang
alte
Liste l
Praktische Informatik I
81
anfang
17
42
37
37
H. Peter Gumm, Philipps-Universität Marburg
Notwendige Operationen
Im Falle der Listen:
„„
Konstruktoren
Konstruktoren, ,
„
… bauen Elemente des Datentyp
… bauen Elemente des Datentyp
… Meist gibt es mehrere Konstruktoren
… Meist gibt es mehrere Konstruktoren
„„
bestimmten
bestimmtenKonstruktor
Konstruktoraufgebaut
aufgebautwurde
wurde
… Hier: ob eine Liste
… Hier: ob eine Liste
leer
leeroder
odernichtleer
nichtleeristist
„„
Eine Liste ist leer, oder nicht leer,
dh. erzeugt durch
… Liste() oder durch
… Liste(int, Liste)
Prädikate
Prädikate
… Testen, ob ein Datenobjekt mit einem
… Testen, ob ein Datenobjekt mit einem
Selektoren
Selektoren
… Liefern die Bestandteile, aus der das
… Liefern die Bestandteile, aus der das
Datenobjekt
Datenobjektaufgebaut
aufgebautwurde
wurde
… Selektoren gehen davon aus, dass das
… Selektoren gehen davon aus, dass das
Datenobjekt
mit
bestimmten
Datenobjektgebaut
miteinem
einem
bestimmten
Konstruktor
wurde
Konstruktor gebaut wurde
Listenkonstruktoren
„
Listenprädikat
…
„
Selektoren
…
Falls die Liste leer ist, hat sie keinen
Bestandteil, braucht also keinen Selektor
…
Ansonsten besteht sie aus den
Bestandteilen.
head() - Kopf, erstes Element
tail() - Liste der restlichen Elemente
…
…
Praktische Informatik I
istLeer()
testet, ob eine Liste leer ist
H. Peter Gumm, Philipps-Universität Marburg
Implementierung: Prädikat, Selektoren
Praktische Informatik I
„
Prädikate sind immer
Boolesche Operationen
„
Die folgenden Selektoren
sind nur anwendbar, falls
istLeer() == false.
„
head : Kopf der Liste
„
tail : Rest der Liste
H. Peter Gumm, Philipps-Universität Marburg
Indexkarte für Listen
„
Beliebige Listenoperationen können sich auf diesen Methoden
abstützen:
Liste
Konstruktoren:
Liste()
Liste(int,Liste)
Methoden:
boolean istLeer()
int
head()
Liste
tail(Liste)
„
Wir verstecken alle anderen Felder und Methoden hinter dem
Schlüsselwort:
private
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Kochrezept für Listenoperationen
„
„
„
llwerden
werdenrekursiv
rekursivdefiniert
definiert
meineMethode(){
meineMethode(){
if(l.istLeer())
if(l.istLeer())
{{ ..
.. Trivialfall
Trivialfall ...}
...}
else
{
else {
…
…
Methoden
Methodenfür
füreine
eineListe
Liste
…
…
Kombiniere
KombiniereResultat
Resultataus
aus
„„ l.head()
l.head() und
und
„„ l.tail().meineMethode()
l.tail().meineMethode()
}}
Eine Liste ist
„
…
„
tail()
Für den Test haben wir
das Prädikat
…
„
head()
und einer Rest-(Liste)
„
istLeer
Für den Zugriff auf die
Bestandteile haben wir
die Selektoren
…
…
Praktische Informatik I
leer, oder
sie hat einen Kopf
head
tail
H. Peter Gumm, Philipps-Universität Marburg
Einfache Listenoperationen
„
Eine Liste
…
istLeer()
oder besteht aus Element
…
head()
und RestListe
…
tail()
Methoden werden rekursiv
definiert
…
Basisfall: leere Liste
„
„
Methoden werden rekursiv
definiert
…
Rekursiver Fall:
„
…
Basisfall: leere Liste
„
…
Meist trivial
Meist trivial
„
„
Zur Verfügung stehen:
head()
tail().methode()
Rekursiver Fall:
„
„
„
Zur Verfügung stehen:
head()
tail().methode()
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
withoutNth als Operation
„
withoutNth
…
Eine Operation
…
Ergebnis:
„
…
Wie
Ausgangsliste
ohne n-tes
Element
Ursprüngliche Liste
bleibt unverändert
neue Zelle
81
tail()
anfang
inhalt next
meineListe
81
anfang
Praktische Informatik I
inhalt next
42
inhalt next
37
inhalt next
14
inhalt next
H. Peter Gumm, Philipps-Universität Marburg
Bäume – 2-dimensionale Listen
„
Bäume sind hierarchische
Strukturen
„
Bäume bestehen aus
…
…
„
Knoten und
Teilbäumen
Bei Binärbäumen hat jeder
Knoten zwei Unterbäume,
…
…
„
Wurzelknoten
den linken Unterbaum
den rechten Unterbaum
In den Knoten kann
Information gespeichert
werden
Praktische Informatik I
Rechter
Teilbaum
Linker
Teilbaum
H. Peter Gumm, Philipps-Universität Marburg
Baumknoten
class Knoten{
Knoten left;
char content;
Knoten right;
}
„
„
Wir implementieren einen Knoten
als Zelle mit zwei Zeigern.
Zur Abwechslung speichern wir
Zeichen in den Knoten
‘+‘
left
inhalt right
‘x‘
left
Praktische Informatik I
inhalt right
‘2‘
left
inhalt right
H. Peter Gumm, Philipps-Universität Marburg
BinTree
„
Die Klasse Knoten ist nur
eine Hilfsklasse für die
Klasse BinTree
„
Wir implementieren sie
daher als innere Klasse
(geschachtelt in BinTree).
class BinTree{
Knoten wurzel;
private class Knoten{
Knoten left;
char content;
Knoten right;
// Konstruktor
Knoten(Knoten b1, char c, Knoten b2){
left = b1;
content = c;
right = b2;
}
}
}
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Konstruktoren, Prädikate, Selektoren
„„
Konstruktoren
Konstruktoren
……
BinTree()
BinTree()
„
„
BinTree ( B1, c, B2)
Der
Derleere
leereBaum
Baum
c
…… BinTree(
BinTree(BB11, ,c,c,BB22))
neuer
neuerBinTree
BinTreemit
mit
„
„
„
„
„
„
„„
linkem
linkemTeilbaum
TeilbaumBB1 1
rechtem
rechtemTeilbaum
TeilbaumBB2 2
Inhalt
Inhaltder
derWurzel:
Wurzel:cc
Prädikat
Prädikat isEmpty
isEmpty
…… Testet,
Testet,ob
obein
einBinTree
BinTreeleer
leerist,
ist,oder
odereinen
einen
rechten
rechtenund
undlinken
linkenTeilbaum
Teilbaumenthält
enthält
„„
B2
B1
Selektoren
Selektorenleft,
left,right,
right,content
content
…… Falls
Fallsder
derBinTree
BinTreenicht
nichtleer
leerist,
ist,liefert
liefert
„ left() den linken Teilbaum
„ left() den linken Teilbaum
„ right() den rechten Teilbaum
„ right() den rechten Teilbaum
„ content() den Inhalt der Wurzel
„ content() den Inhalt der Wurzel
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Implementierung
class
class BinTree{
BinTree{
private
private Knoten
Knoten wurzel;
wurzel;
//
// Konstruktoren
Konstruktoren
BinTree(){};
BinTree(){};
„
Implementierung verläuft
analog zu Listen
//
// der
der leere
leere Baum
Baum
BinTree(BinTree
BinTree(BinTree b1,
b1, char
char c,
c, BinTree
BinTree b2){
b2){
wurzel
=
new
Knoten(b1.wurzel,c,b2.wurzel);
wurzel = new Knoten(b1.wurzel,c,b2.wurzel);
}}
//
// Prädikat
Prädikat
boolean
boolean isEmpty(){
isEmpty(){ return
return wurzel==null;
wurzel==null; }}
//
// Selektoren
Selektoren
BinTree
BinTree left(){
left(){
BinTree
BinTree ll == new
new BinTree();
BinTree();
l.wurzel
l.wurzel == this.wurzel.left;
this.wurzel.left;
return
l;
return l;
}}
//this
//this nicht
nicht nötig
nötig
char
char content(){
content(){ return
return this.wurzel.content;
this.wurzel.content; }}
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Indexkarte für BinTree
„
Beliebige BinTree-Operationen können sich auf
diesen Methoden abstützen:
BinTree
Konstruktoren:
BinTree()
BinTree(BinTree,char,BinTree)
Methoden:
boolean isEmpty()
BinTree left()
char
content()
BinTree right()
„
Wir verstecken alle anderen Felder und Methoden
hinter dem Schlüsselwort private
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Rekursion auf Binärbäumen
„
Binärbäume sind induktiv definiert
…
…
„
BinTree ( B1, s, B2)
Der leere Baum ist ein Binärbaum
Sind B1 und B2 Binärbäume und s ein String, dann ist der
Baum mit Wurzel s, linkem Teilbaum B1 und rechtem
Teilbaum B2 ein Binärbaum
*
Operationen f auf Binärbäumen sind rekursiv
-
+
…
…
„
5
*
x
Beispiel: tiefe (engl.: depth)
…
…
„
Falls isEmpty(B): gib f(B) direkt an
Ansonsten beschreibe wie sich der Wert von f aus f(B1),
f(B2) und s ergibt.
Falls isEmpty(B) : 0
Ansonsten max( left().depth(), right.depth() ) + 1
Beispiel: exists(char c) (ist c vorhanden ?)
…
…
Falls isEmpty(B) : false
Ansonsten:
left().exists(c) || content()== c || right().exists(c)
Praktische Informatik I
3
y
depth: 4
Dieser Baum repräsentiert
(x+3*y)*(-5)
H. Peter Gumm, Philipps-Universität Marburg
Einfache Baumoperationen
class XBinTree extends BinTree{
int depth(){
if(isEmpty()) return 0;
else return
max( ((XBinTree)left()).depth()
((XBinTree)right()).depth()) +1;
}
boolean exists(char c){
if(isEmpty()) return false;
else return
((XBinTree)left()).exists(c)
|| content()==c
|| ((XBinTree)right()).exists(c);
}
„
isEmpty(), left(),
right() werden aus der
Oberklasse geerbt.
„
left() liefert einen
BinTree()
„
depth() ist nur in der
Unterklasse definiert – für
XBinTrees
„
Wir brauchen casts um die
BinTrees in XBinTrees zu
verwandeln
„
Hilfsmethode max ist nicht
an ein Objekt gebunden.
Wir erklären sie als
Klassenmethode, also
static.
„
Das sie nur hier gebraucht
wird, verstecken wir sie mit
private.
private static int max(int x, int y) {
return (x < y)? y : x;
}
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Bäume mit Blättern
„
Jeder Zweig soll in einem
Blatt enden
„
Die Information speichern
wir in den Blättern
„
“Paul“
“Anna“
“Eva“
Jeder Knoten hat zwei
Unterbäume
class Knoten{
“Peter“
“Otto“
class Blatt{
Knoten links;
Knoten rechts;
String info;
}
}
Wir haben ein Problem: Wir müssen auch zulassen :
Blatt links;
Blatt rechts;
Praktische Informatik I
... aber ein Blatt ist kein Knoten !
H. Peter Gumm, Philipps-Universität Marburg
Wie kann man Klassen vereinigen ?
„
Wir wollen Blatt und Knoten zu einer
Klasse Baum zusammenfassen.
„
Blatt wird Unterklasse von Baum
Knoten wird Unterklasse von Baum
„
„
class Blatt extends Baum
class Knoten extends Baum
Viele Methoden müssen für alle
Bäume funktionieren
…
…
…
…
istBlatt()
istKnoten
depth()
draw()
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Default-Methoden redefinieren
„
In Baum definieren wir die Methoden irgendwie:
boolean isBlatt(){
return false; // äähm na ja ...
}
void draw(){ }
// tu nix
„
In den Unterklassen redefinieren wir sie wieder
// z.B. in Blatt:
boolean isBlatt {
return true;
}
void draw(
System.out.println(info);
}
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
besser: Abstrakte Klassen
„
„
Vereinigung von Unterklassen
Gemeinsame Methoden
…
In der Oberklasse abstrakt
erklärt
„
…
„
…
…
class Knoten
“Pete“
“Eva“
In jeder nicht abstrakten
Unterklasse implementiert
Jedes Blatt ist ein Baum
Jeder Knoten ist ein Baum
Definiere Baum als abstrakte
Klasse, die Blatt und Knoten
umfasst
Praktische Informatik I
class Blatt
“Ann“
Nur die Signatur wird
aufgeführt
Beispiel
…
abstract class Baum
“Jon“
“Paul“
Abstrakte Methoden
istKnoten
draw
istBlatt
depth
…etc. …
H. Peter Gumm, Philipps-Universität Marburg
Abstrakte Klasse Baum
„
Klassen werden wechselseitig rekursiv
abstract class Baum{
…
}
Jeder Knoten
ist ein Baum
“Eva“
“Ann“
“Pete“
class Knoten extends Baum{
Baum links;
Baum rechts;
…
}
Jedes Blatt
ist ein Baum
Praktische Informatik I
class Blatt extends Baum{
String info;
}
“Eva“
“Jon“
“Paul“
H. Peter Gumm, Philipps-Universität Marburg
Implementierung
„
„
abstract class Baum{
Abstrakte Methoden
müssen in (konkreten)
Unterklassen implementiert
werden
Wird vom Compiler geprüft
class Knoten extends Baum{
Baum links, rechts;
abstract boolean istBlatt();
abstract int depth();
…
}
class Blatt extends Baum{
String info;
boolean istBlatt(){
return false;}
int depth(){
return
1+max(links.depth(),
rechts.depth());
}
boolean istBlatt(){
return true;}
int depth(){ return 0; }
…
}
}
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Operationen auf rekursiven Daten
„
Funktionen auf induktiv
definierten Daten sind rekursiv
am einfachsten
…
Beispiel : draw()
„
„
…
Hilfsfunktion draw(int n)
Malt einen Baum ab Spalte n
Rote Verbindungslinien nur
zur weiteren Hervorhebung
In Blatt:
println(info);
…
In Knoten:
links.draw(n+2);
println(„+“);
rechts.println(n+2);
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Abstrakte Klassen
„
haben keine eigenen Objekte
…
…
„
Was sollte auch new Baum() liefern:
ein Blatt oder einen Knoten ?
können abstrakte und konkrete Methoden
enthalten
abstract boolean istBlatt();
boolean istKnoten(){
return !istBlatt(); }
„
Sobald eine Methode abstrakt ist, muss
die ganze Klasse abstrakt erklärt werden
„
Der Compiler achtet darauf, dass jede
abstrakte Methode in jeder Unterklasse
implementiert wird.
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Listen als abstrakte Klassen
„
Listen sind leer oder nicht leer
…
…
Nichtleere Listen haben head
und tail
Die leere Liste hat kein Feld
„
Traditionell heißt der Konstruktor
einer nichtleeren Liste Cons
„
Die leere Liste nennt man Nil
„
Wir definieren Liste als
abstrakte Klasse, Cons und
Nil als (konkrete) Unterklassen
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Die abstrakte Klasse List
abstract
abstract class
class List{
List{
abstract
abstract boolean
boolean istLeer();
istLeer();
abstract
abstract int
int length();
length();
//
// Prüft,
Prüft, ob
ob nn in
in der
der Liste
Liste vorkommt
vorkommt
abstract
boolean
exists(int
n);
abstract boolean exists(int n);
//Hängt
//Hängt ll vorne
vorne an
an die
die Liste
Liste an
an
abstract
List
prepend(List
l);
abstract List prepend(List l);
//Hängt
//Hängt ll hinten
hinten an
an die
die Liste
Liste an
an
abstract
List
append(List
l);
abstract List append(List l);
//Darstellung
//Darstellung im
im Terminal
Terminal Fenster
Fenster
abstract
void
draw();
abstract void draw();
}}
abstract
abstract void
void niceDraw();
niceDraw();
Auch eine List - im alten Griechenland
Praktische Informatik I
H. Peter Gumm, Philipps-Universität Marburg
Cons und Nil
class
class Cons
Cons extends
extends List{
List{
int
content;
int content;
List
List next;
next;
class
class Nil
Nil extends
extends List{
List{
//
// keine
keine Felder
Felder
//
// Konstruktor
Konstruktor
Cons(int
Cons(int inhalt,
inhalt, List
List rest){
rest){
content
=
inhalt;
next
content = inhalt; next == rest;}
rest;}
//
// Konstruktor
Konstruktor
Nil(){};
Nil(){};
//Prädikat
//Prädikat
boolean
boolean istLeer(){return
istLeer(){return false;}
false;}
//
// Prädikat
Prädikat
boolean
boolean istLeer(){return
istLeer(){return true;}
true;}
//
// Selektoren
Selektoren
int
int head(){
head(){ return
return content;
content; }}
//
// Selektoren:
Selektoren:
//
keine,
// keine, da
da keine
keine Bestandteile
Bestandteile
List
List tail(){
tail(){ return
return next;
next; }}
//
// Luxus
Luxus (optionale
(optionale Funktionen)
Funktionen)
int
length(){
int length(){
return
return 1+tail().length();
1+tail().length();
}}
...
...
}}
Praktische Informatik I
//
// Luxus
Luxus (optionale
(optionale Funktionen)
Funktionen)
int
length(){
int length(){
return
return 0;
0;
}}
...
...
}}
H. Peter Gumm, Philipps-Universität Marburg
Herunterladen