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...

Post on 12-May-2018

218 views 4 download

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: tnattkem@techfak.uni-bielefeld.de

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