A lgo rith me n u n d D a te n stru k tu re n II n io rp rof esso r Dr .-In g. T im W. Na ttk emp er...
-
Upload
nguyenmien -
Category
Documents
-
view
218 -
download
4
Transcript of A lgo rith me n u n d D a te n stru k tu re n II n io rp rof esso r Dr .-In g. T im W. Na ttk emp er...
Algorithmen und Datenstrukturen II
Algorithmen und Datenstrukturen II 1
Juniorprofessor Dr.-Ing. Tim W. Nattkemper
Raum: M7-130
Sprechstunde: Di 13:00 ct - 14:00
Tel.: 0521/106-6059
Email: [email protected]
Algorithmen und Datenstrukturen II 2
Syntax und Semantik
Algorithmen und Datenstrukturen II 3
Einfuhrung
Programmiersprachen sind formale Sprachen. Es ist prazise festgelegt,
• welche Zeichenreihen uberhaupt Programme einer Sprache L sind (Syntax),
• welche Ein-/Ausgabefunktion ein Programm berechnet (Semantik).
Algorithmen und Datenstrukturen II 4
Konkrete/abstrakte Syntax
konkrete Syntax: genaue textuelle Aufschreibung fur Programme.
abstrakte Syntax: Bindeglied zur Semantik; gibt an, wie ein Programm(-stuck)
aufgebaut ist.
Algorithmen und Datenstrukturen II 5
Beispiel 0.1
abstrakt
assign
!!"
##$
x add
!!"
##$
var const
!!"
##$
y 5
konkret
x := y + 5 Pascal
x = y + 5 C, Fortran, Java
LET x = y + 5 Basic (anno 1963)
ADD 5 TO y GIVING x COBOL
STORE y + 5 TO x dBase
Algorithmen und Datenstrukturen II 6
Operatoren und Konstrukte
In der abstrakten Syntax tauchen die primitiven Konstrukte einer Programmiersprache
auf, sowie Operatoren, die diese zu neuen Konstrukten kombinieren.
primitiv: Bezeichner, Zahl
Kombination: var: Bezeichner → Ausdruck
const: Zahl → Ausdruck
add: Ausdruck × Ausdruck → Ausdruck
assign: Bezeichner × Ausdruck → Anweisung
Algorithmen und Datenstrukturen II 7
Worter
Definition 0.2
• Ein Alphabet A ist ein endlicher Zeichenvorrat (eine endliche Menge).
• Die Mengen aller endlichen Zeichenreihen uber einem Alphabet A bezeichnenwir mit A!.
• Das leere Wort der Lange 0 bezeichnen wir mit ε.
Algorithmen und Datenstrukturen II 8
Formale Sprachen
Definition 0.3 Eine Menge L ⊆ A! heißt formale Sprache uber dem Alphabet A.
Einen abstrakteren Sprachbegriff kann man kaum definieren. Die einzige Frage, die
man sich uber w ∈ A! stellen kann, ist: Gilt w ∈ L oder w %∈ L? Diese Frage nennt
man das Wortproblem von L.
Algorithmen und Datenstrukturen II 9
Programmiersprachen
Definition 0.4 Eine Programmiersprache ist ein Paar (L,L), wobei L ⊆ A! eineformale Sprache und L : L → (A! → A!) die Semantik von L ist.
Damit ordnet L jedem L-Programm l ∈ L als seine Bedeutung die
Ein-/Ausgabefunktion L(l) zu, wobei Ein- und Ausgabe ebenfalls Zeichenreihen uber
A sind. Fur L(l) schreiben wir auch kurz Ll.
Algorithmen und Datenstrukturen II 10
Kontextfreie Grammatiken
Definition 0.5 Eine kontextfreie Grammatik ist ein 4-Tupel G = (N,A, P, S),wobei
1. N ein Alphabet von sogenannten Nonterminalsymbolen,
2. A ein Alphabet von sogenannten Terminalsymbolen mit N ∩A = ∅,
3. P eine endliche Menge von Produktionen (Regeln) der Form V → α mitV ∈ N und α ∈ (V ∪A)! und
4. S ∈ N ein Startsymbol ist.
Algorithmen und Datenstrukturen II 11
Satzformen einer Grammatik
Die Menge S(G) der Satzformen von G ist die kleinste Teilmenge von (N ∪A)! mit
den folgenden Eigenschaften:
1. S ∈ S(G).
2. Wenn αV β ∈ S(G) fur ein Nonterminalsymbol V ∈ N und Zeichenfolgen
α, β ∈ (N ∪A)! und wenn V → γ ∈ P eine Regel ist, so gilt auch αγβ ∈ S(G)(”Ableitungsschritt“).
Algorithmen und Datenstrukturen II 12
Sprache einer Grammatik
Die durch G definierte Sprache ist L(G) def= S(G) ∩A!. Den Test, ob ein gegebenes
Wort w durch eine Grammatik G erzeugt werden kann, also ob w ∈ L(G) gilt, nennt
man das Wortproblem von G.
Algorithmen und Datenstrukturen II 13
Syntax und Semantik von Sprachen:
Bohrkopfsteuerung
N
S
EW
O
N,E, W, S: Bewegung um 1 Gitterpunkt (north, east, west, south)
O: Einstellen auf Nullpunkt (origin)
D: Senken des Bohrkopfes mit Bohrung (drill)
U : Heben des Bohrkopfes (up)
Algorithmen und Datenstrukturen II 14
Programme zur Maschinensteuerung sind z.B.
“ONNNEEDO” Bohrung am Punkt (2,3) mit Ruckkehr zum Nullpunkt
“ODUDUDU” Dreifach-Bohrung am Nullpunkt
“DUNDUWDUSDU” bohrt Gitterquadrat, wo der Kopf gerade steht
Algorithmen und Datenstrukturen II 15
In der ersten Variante unserer Steuersprache lassen wir beliebige Befehlsfolgen zu.
Außerdem kann jedes Programm als Eingabe ein Paar von Start-Koordinaten erhalten.
L1 = {N,E, W, S, U, D, O}!
Eingabe: (Int, Int)
L1 : L1 → (Int, Int) → [(Int, Int)]
Algorithmen und Datenstrukturen II 16
Maschinenzustand
x aktuelle x-Koordinate
y aktuelle y-Koordinate
l aktueller Hebezustand des Bohrkopfes: 0 gesenkt, 1 oben
cs Liste bisheriger Bohr-Koordinaten
Algorithmen und Datenstrukturen II 17
Semantik von Befehlen
bef :: Befehl → Zustand → Zustand
bef b (x, y, l, cs) = case b of
O → (0, 0, 1, cs)
N → (x, y + 1, l, cs)
W → (x− 1, y, l, cs)
S → (x, y − 1, l, cs)
E → (x + 1, y, l, cs)
D → (x, y, 0, (x, y) : cs)
U → (x, y, 1, cs)
Algorithmen und Datenstrukturen II 18
Befehlsfolgen
beff :: Befehl! → Zustand → [(Int, Int)]
beff [ ](x, y, l, cs) = reverse cs
beff (b : bs)(x, y, l, cs) = beff bs(bef b (x, y, l, cs))
Die Semantik L1 wird beschrieben durch die Funktion
prog :: Befehl! → (Int, Int) → [(Int, Int)]
prog bs (i, j) = beff bs (i, j, 1, [])
Algorithmen und Datenstrukturen II 19
Programmiersprache L1 und ihre Semantik L1 sind sehr naiv. Man sollte zum Beispiel
bedenken, dass das Werkstuck und vielleicht auch die Maschine beschadigt werden,
wenn mit abgesenktem Bohrkopf Bewegungen ausgelost werden. Freilich – solange
niemand solche Steuerprogramme erzeugt, geht alles gut. Jedoch wollen wir uns nicht
darauf verlassen . . .
Algorithmen und Datenstrukturen II 20
Syntaktische vs. semantische Verfeinerung
Generell gibt es zwei Moglichkeiten, eine Sprache (L,L) zu verfeinern: syntaktisch
oder semantisch.
Semantisch heisst: das“Ungluck”kann programmiert werden, tritt aber nicht ein.
Syntaktisch heisst: das“Ungluck”wird bereits als syntaktisch fehlerhaftes Programm
abgewiesen.
Algorithmen und Datenstrukturen II 21
Aufgabe 0.6 Modifiziere die Semantik L1 (bei unverandertem L1) in zweiverschiedenen Weisen. Tritt eine Bewegung mit abgesenktem Bohrkopf auf, sowird
a) die Ausfuhrung des Programms abgebrochen und nur die Koordinaten derbisherigen Bohrungen ausgegeben,
b) die Ausfuhrung des Programms abgebrochen und keine Koordinatenangegeben.
Algorithmen und Datenstrukturen II 22
Forderungen an die Steuersprache
Wir entscheiden uns nun fur die syntaktische Verfeinerung und stellen Forderungen an
die Steuersprache L:
1. Auf Befehl D muss stets U oder O folgen.
2. Befehl O ist immer moglich, U nur unmittelbar nach D.
3. Alle Programme enden mit dem Bohrkopf am Nullpunkt.
4. Auf dem Weg von einer Bohrung zur nachsten sind gegenlaufige
Richtungswechsel unerwunscht, zum Beispiel . . . NSNS . . . oder . . . NES . . . ,
weil sie die Maschine in Schwingung versetzen konnen.
Alle diese Forderungen lassen sich durch Einschrankungen von L1 erfullen, erfordern
aber verfeinerte Methoden zur syntaktischen Sprachbeschreibung. Solche Mittel sind
Grammatiken.
Algorithmen und Datenstrukturen II 23
Grammatik 1
Grammatik G1 (zur Beschreibung von L1)
A = { N,E, W, S, U, D, O}N = { moves,move}S = moves
P = { moves → ε| move moves
move → N |E|W |S|U |D|O}
Hier gilt L(G1) = A!. Es ist w ∈ L(G1) mit
w = “WENDEDENUDOSUED""
Ubung: Leite w mit dieser Grammatik ab.
Algorithmen und Datenstrukturen II 24
Verfeinerte Grammatik 2
Verfeinerte Grammatik G2 (berucksichtigt Forderungen (1) - (3), aber nicht (4)).
A, N, S wie G1
P = { moves → O|DO| move moves
move → N |E|W |S|O|DU |DO}
Frage: Warum brauchen wir die Regel moves → DO uberhaupt?
Algorithmen und Datenstrukturen II 25
Verfeinerte Grammatik 2
Verfeinerte Grammatik G2 (berucksichtigt Forderungen (1) - (3), aber nicht (4)).
A, N, S wie G1
P = { moves → O|DO| move moves
move → N |E|W |S|O|DU |DO}
Frage: Warum brauchen wir die Regel moves → DO uberhaupt?
Antwort: Sonst ist “DO” /∈ S(G2).
Algorithmen und Datenstrukturen II 26
Warum ist nun w =“WENDEDENUDOSUED” /∈ S(G2)?
Versuch einer Ableitung:
moves → move moves
→ W moves
→ W moves moves
→ W E moves
→3 W E N move moves
→ W E N ?
Hier kann nur DU oder DO erzeugt werden, aber nicht D allein oder DE.
Algorithmen und Datenstrukturen II 27
Verfeinerte Grammatik 3
Verfeinerte Grammatik G3 (berucksichtigt Forderungen (1) und (4), (2) nur
teilweise und (3) gar nicht):
A, S wie G1
N = { moves, ne, nw, se, sw, drill }P = { moves → ε | ne moves | nw moves | se moves | sw moves
ne → N ne | E ne | drill
se → S se | E se | drill
nw → N nw | W nw | drill
sw → S sw | W sw | drill
drill → DU |DO }
Algorithmen und Datenstrukturen II 28
RNA-Sekundarstrukturen
Ein RNA-Molekul besteht aus Basen A,C,G,U. Durch Wasserstoff-Brucken zwischen
A–U, G–C, G–U bilden sich Basenpaarungen, die zu einer Sekundarstruktur fuhren.
Primarsequenz Sekundarstruktur
C A C C U A A G G U C C
C
A U
C C
C A C C U A A G G U C C
A
U A
C G
C G← Helix-Bildung schafft Stabilitat
Algorithmen und Datenstrukturen II 29
Sekundarstruktur-Grammatik
Grammatik zur Beschreibung der Sekundarstruktur (Ausschnitt):
A = { A, C, G, U }N = { struct, any, stack, loop }S = struct
P = { struct → any | any struct | struct any | stack | ε
any → A | C | G | U
stack → A stack U | U stack A |G stack C | C stack G |G stack U | U stack G | loop
loop → any loop | any any any }
Algorithmen und Datenstrukturen II 30
Ableitung von RNA-Sequenzen
Allein mit den ersten beiden Produktionen kann man alle RNA-Sequenzen ableiten:
struct → any struct → A struct → A any struct → AC struct . . .
Damit ist L(G) = A!. Der Witz der Grammatik ist, dass manche Ableitungen das
Vorliegen moglicher Sekundarstrukturen anzeigen – dann namlich, wenn sie die
Produktionen fur stack benutzen.
Algorithmen und Datenstrukturen II 31
Ableitung == Struktur
struct →2 C struct →4 C struct CC → C stack CC
→ CA stack UCC →2 CACC stack GGUCC → CACC loop GGUCC
→4 CACCUAAGGUCC
Algorithmen und Datenstrukturen II 32
Syntaxbaumstruct!!
any!!
Cstruct""
any""
Cstruct""
any""
Cstruct
stack!!A
""Ustack!!
C""
Gstack!!C
""Gstack
loop!!
any!!
U
""any
""A
any
A
Algorithmen und Datenstrukturen II 33
Chomsky-Hierarchie
Typ 0: XaY b → cXZ (allgemein)
Typ 1: aXb → aZY b (kontextsensitiv)
Typ 2: X → aY bZc (kontextfrei)
Typ 3: X → aY (regular)
Algorithmen und Datenstrukturen II 34
Komplexitat des Wortproblems
Typ 0: unentscheidbar
Typ 1: exponentiell
Typ 2: polynomiell (Θ(n3) oder besser; bei Grammatiken fur Programmiersprachen in der Regel
Θ(n))
Typ 3: linear
Algorithmen und Datenstrukturen II 35
EBNF, Historisches
• Syntaxbeschreibung von FORTRAN und COBOL (am Anfang) durch Beispiele
und Gegenbeispiele.
• 1958 formale Beschreibung der Syntax von ALGOL durch John Backus;
Backus-Normalform (BNF).
• Kleine Verbesserungen in der Notation durch Peter Naur, daher spricht man
heute von der Backus-Naur-Form (BNF).
• Niklaus Wirth hat die Backus-Naur-Form noch einmal uberarbeitet und erweitert
(EBNF – Extended BNF).
Algorithmen und Datenstrukturen II 36
EBNF, Definition
Die Metazeichen der EBNF (vgl. Klaeren [5], S. 104) sind:
das Definitionszeichen =
das Alternativzeichen |die Anfuhrungszeichen
die Wiederholungsklammern { }die Optionsklammern [ ]
die Gruppenklammern ( )
der Punkt .
Algorithmen und Datenstrukturen II 37
EBNF, Terme
Die Menge ET der EBNF-Terme ist gegeben durch:
1. Ist V eine Folge von Buchstaben und Ziffern, die mit einem Buchstaben beginnt,
so gilt V ∈ ET und gilt als Nonterminalsymbol.
2. Ist w eine Folge von beliebigen Symbolen, so ist “w”∈ ET und gilt als ein (!)
Terminalsymbol.
3. Fur α ∈ ET sind auch
(a) (α) ∈ ET ,
(b) [α] ∈ ET und
(c) {α} ∈ ET .
4. Fur α1, . . . ,αn ∈ ET sind auch
(a) α1| . . . |αn ∈ ET und
(b) α1α2 . . .αn ∈ ET .
Algorithmen und Datenstrukturen II 38
Eine EBNF-Definition besteht aus einer endlichen Menge von EBNF-Regeln der Form
V = α.
wobei V ein Nonterminalsymbol entsprechend obiger Konvention und α ein
EBNF-Term ist. Das Nonterminalsymbol auf der linken Seite der ersten Regel ist das
Startsymbol.
Algorithmen und Datenstrukturen II 39
EBNF-Definition fur Mini-Java
Algorithmen und Datenstrukturen II 40
program =“class” ident“{”mainMethod“}”.
mainMethod =“public”“static”“void”“main”“(”“String”“[”“]” argsIdent“)”block.
statement =“int” ident“=” expression“;”
| ident“=” expression“;”
|“if”“(” condition“)” statement
|“while”“(” condition“)” statement
| block
|“System”“.”“out”“.”“println”“(” expression“)”“;”
|“;”|“int”“[”“]” arrayIdent“=”“new”“int”“[” expression“]”“;”
| arrayIdent“[” expression“]”“=” expression“;”.
block =“{”{ statement }“}”.
condition = expression ( “==” |“!=” |“<” |“<=” |“>” |“>=” ) expression.
expression = [ ( “+” |“-” ) ] term { ( “+” |“-” ) term }.term = factor { ( “*” |“/” ) factor }.factor = ident
| number
|“(” expression“)”
|“Integer”“.”“parseInt”“(” argsIdent“[” expression“]”“)”
| argsIdent“.”“length”
| arrayIdent“.”“length”
Algorithmen und Datenstrukturen II 41
| arrayIdent“[” expression“]”.
ident = ( letter |“_” |“$” ) { letter | digit }.number = (“0” | digit { digit |“0”} ).
digit =“1” |“2” | . . . |“9”.letter =“A” | . . . |“Z” |“a” | . . . |“ z”.
argsIdent = ident.
arrayIdent = ident.
Algorithmen und Datenstrukturen II 42
Operationen auf Sprachen
Seien L, L1 und L2 beliebige Sprachen (Wortmengen) uber einem gemeinsamen
Alphabet. Dann definieren wir:
1. Komplex-Produkt: L1L2def= {w1w2 | w1 ∈ L1, w2 ∈ L2}
(also L∅ = ∅L = ∅; L{ε} = {ε}L = L)
2. n-fache Iteration: L0 def= {ε}, Ln+1 := LLn
3. Stern-Operation: L! def=!
n#N Ln
Algorithmen und Datenstrukturen II 43
Beispiele
1. {aa, ab} {aa, ε} = {aaaa, abaa, aa, ab}
2. {a, b, c}2 = {a, b, c} {a, b, c} = {aa, ab, ac, ba, bb, bc, ca, cb, cc}
3. {a, b}! = {ε, a, b, aa, ab, ba, bb, . . . }
Algorithmen und Datenstrukturen II 44
Semantik der EBNF
Die Semantik der EBNF definieren wir durch Rekursion uber die EBNF-Terme. Sei Eeine EBNF-Definition (wobei S das Startsymbol, N die Menge der Nonterminals und
A die Menge der Terminals sei) und ET die Menge der EBNF-Terme. Dann ist die
von E erzeugte Sprache L(E) definiert als !S"E , wobei
! "E : ET ! P (A!)
wie folgt definiert ist (vgl. Klaeren [5], S. 107):
1. Fur V ∈ N ist !V "Edef=
"#
$!α"E falls V = α. eine Regel in E ist
∅ sonst
2. !“w”"Edef= {w}
3.#(α)
$E
def= !α"E
4.#[α]
$E
def= {ε} ∪ !α"EAlgorithmen und Datenstrukturen II 45
5.#{α}
$E
def= !α"!E
6. !α1 . . .αn"Edef= !α1"E . . . !αn"E
7. !α1 | · · · | αn"Edef= !α1"E ∪ · · · ∪ !αn"E
Algorithmen und Datenstrukturen II 46
Beispiel
Gegeben sei die EBNF-Definition E mit dem Startsymbol Rna sowie den beiden Regeln
Rna = Any [“A”]
und Any = (“A” | “C” | “G” | “U”).
Durch wiederholte Anwendung der verschiedenen Gleichungen aus der
Semantikdefinition ergibt sich die von dieser EBNF definierte Sprache
folgendermaßen:
Algorithmen und Datenstrukturen II 47
RNA-Sprache
!Rna"E(1)=
#Any [“A”]
$E
(6)= !Any"E
#[“A”]
$E
(1),(4)=
#(“A” | “C” | “G” | “U”)
$E%{ε} ∪ !“A”"E
&
(3),(2)= !“A” | “C” | “G” | “U”"E
%{ε} ∪ {A}
&
(7)=
'!“A”"E ∪ !“C”"E ∪ !“G”"E ∪ !“U”"E
({ε, A}
=%{A} ∪ {C} ∪ {G} ∪ {U}
&{ε, A}
= {A,C,G,U}{ε, A}= {A,C,G,U,AA,CA,GA,UA}.
Algorithmen und Datenstrukturen II 48
Beispiel eines syntaktisch korrekten
Mini-Java-Programms
Algorithmen und Datenstrukturen II 49
class BubbleSort {
public static void main(String[] args) {
int[] array = new int[args.length];
int i = 0;
while (i < args.length) {
array[i] = Integer.parseInt(args[i]);
i = i+1;
}
i = 1;
while (i < array.length) {
int j = array.length - 1;
while (j >= i) {
if (array[j] < array[j-1]) {
int tmp = array[j];
array[j] = array[j-1];
array[j-1] = tmp;
}Algorithmen und Datenstrukturen II 50
j = j-1;
}
i = i+1;
}
i = 0;
while (i < array.length) {
System.out.println(array[i]);
i = i+1;
}
}
}
Algorithmen und Datenstrukturen II 51
Syntaxdiagramme
Eine EBNF-Definition kann man folgendermaßen in Syntaxdiagramme uberfuhren:
“w” : %!"#$
w % fur alle w ∈ A.
V : % V % fur alle V ∈ N .
[α] :
%
& %
α
Algorithmen und Datenstrukturen II 52
{α} : &
'
%
α
α1 . . .αn : % α1 % · · · % αn %
α1 | · · · | αn : % α1 %...
% αn
(
Algorithmen und Datenstrukturen II 53
Beispiel: Syntaxdiagramme fur Mini-Java
!"# $% !## # # ##program
ident { }mainMethodclass
%& '( %& '( %& '(%& '() %& '( ) ) )
% % % %
%%%%%%%%
staticpublic void main
( [ ] argsIdent ) blockString
mainMethod
Algorithmen und Datenstrukturen II 54
%& '( ))%& '( )%& '( ) )
%& '()
) ) )
) ) )))))%& '(%& '(
%& '( ) %& '( ) %& '( ) ) )
))
)%
%
%(
% % % %
%
%(
(% % %%
%% %
% %
%
% % %
(%
% % % % %(
(
%%
%%%%%%
%
% % % % % % %%(
%(
% %%
statement
int = expression ;ident
if ( statement)condition
while condition )( statement
int
;
[ ] arrayIdent =
expression ] = expression ;[arrayIdent
;]expression[intnew
System . out . println ( ) ;expression
block
ident expression ;=
Algorithmen und Datenstrukturen II 55
&'()&'()# #
$ %
#block
{
statement
}
Algorithmen und Datenstrukturen II 56
*+,-
*+,-*+,-*+,-
*+,-
*+,-% %
%(% %
%(
%
&
%
%
(
(
expression expression==
!=
<
>=
>
<=
condition
Algorithmen und Datenstrukturen II 57
&'()&'() &'()&'()#
#
#
$
$
#$ %
%
%$
expression
+
-
term
-
term +
$
%
&'()&'()# #
%
%
factor
term
/
*
factor
Algorithmen und Datenstrukturen II 58
! !
! "# $%"# $%
"# $% !!! !
"# $% ! ! ! !
#
#
#
#
#
#
# #
#
#
#
#
# #
# # # #
# # # # # #$
#$
$
$
$
$
factor
number
( expression )
argsIdent
arrayIdent
.
.
length
length
Integer .
arrayIdent ][ expression
parseInt ( argsIdent [ expression ] )
ident
*+,-*+,-
%
%
%(
(
(
(
%
'
'
ident
letter
letter
digit
_
$
Algorithmen und Datenstrukturen II 59
*+,- *+,-% %
%
(
('
'
(digit
digit
0
0
number
Algorithmen und Datenstrukturen II 60
*+,-*+,-
*+,-%
%
%(
(%
digit
1
...
9
*+,-*+,-
*+,-*+,-
*+,-*+,-
%
%
%(
(%
%
%
%
(
(
(
letter
...
A
Z
a
z
...
% %ident
argsIdent
% %ident
arrayIdent
Algorithmen und Datenstrukturen II 61
Literatur
[1] K. Arnold, J. Gosling: JavaTM - Die Program-miersprache. Addison-Wesley, 1996.
[2] T.H. Cormen, C.E. Leierson, R.L. Rivest: In-troduction to Algorithms. MIT Press, 1990.
[3] D. Flanagan: Java in a Nutshell. O’Reilly &Associates Inc., 1996.
[4] F. Jobst: Programmieren in Java. Hanser Ver-lag, 1996.
[5] H. Klaeren: Vom Problem zum Programm.2.Auflage, B.G. Teubner Verlag, 1991.
[6] K. Echtle, M. Goedicke: Lehrbuch der Pro-grammierung mit Java. dpunkt-Verlag, 2000.
Algorithmen und Datenstrukturen II 61-1