Informatik Vorlesung Wintersemester 2003

Werbung
Informatik
Vorlesung
Wintersemester 2003
Johannes Waldmann, HTWK Leipzig
30. Januar 2004
Informatik, Algorithmen (10. 10. 03)
Informatik—Überblick
• Informatik: Wissenschaft von der Verarbeitung
symbolischer Informationen
• durch Algorithmen
• implementiert als Programm
• ausgeführt auf (einem oder mehreren) Rechnern
Teilgebiete der Informatik
(HKF S. 23 ff).
• Theoretische: Automatentheorie, Algorithmentheorie,
Berechenbarkeit, Komplexität
• Praktische: Programm- und Software-Entwicklung,
Dienst- und Arbeitsprogramme (Compiler,
Betriebssysteme, Datenbanken, . . . )
• Technische: Hardware (Prozessor, Speicher, Peripherie,
Netze, Kommunikation)
• Angewandte:
Inhalt (1. Semester)
• Grundlagen der Informatik: Algorithmen
– Definition, Beispiele
– Entscheidbarkeit, Komplexität
• Praktische Informatik: Software
–
–
–
–
–
–
einfache Daten und Kontrollstrukturen
Unterprogramme, Klassen, Methoden
konkrete Datentypen: Listen, Bäume
Algorithmen für Bäume und Graphen
abstrakte Datentypen, Spezifikationen, Interfaces
effiziente Datenstrukturen: Listen, Bäume, Hashing
Inhalt (2. Semester)
• Technische Informatik: Hardware
– maschinelle Darstellung von Information
– Rechner-Aufbau: Prozessor, Speicher
– Peripherie-Geräte: Monitore, Drucker, . . .
• Praktische/Angewandte Informatik:
– Betriebssysteme: Resourcen-Verwaltung und -Teilung
– Netze, Kommunikation, Standards, Protokolle
Empfohlene Literatur/Links
• Webseite zur Vorlesung/Übung, mit Skript, Folien,
Aufgaben: http://www.imn.htwk-leipzig.de/
˜waldmann/ws03/informatik/
• Lehrbuch (Allgemeines, Grundlagen): Horn, Kerner,
Forbrig: Lehr- und Übungsbuch Informatik,
Fachbuchverlag (dritte Auflage, 1. Band: Grundlagen und
Überblick)
http://www.inf.tu-dresden.de/˜fachbuch/
• Software: BlueJ http://www.bluej.org/
• Lehrbuch (Programmieren): David J. Barnes / Michael
Kölling: Objektorientierte Programmierung mit Java (Eine
praxisnahe Einführung mit BlueJ)
http://www.pearson-studium.de/main/main.
asp?page=shop/bookdetails&ProductID=37199
Organisation, Leistungsnachweise
• Vorlesung
– ungerade, freitags, 7:30–11:00, Li207
• Seminare: Einschreibung über ein Web-Interface,
http://www.imn.htwk-leipzig.de/˜waldmann/
autotool.html
– gerade, montags, 7:30–11:00, Li108
– oder gerade, freitags, 9:30–12:45, HB202
Nach Ankündigung Seminare im Computer-Pool
(voraussichtlich ab 11. November)
• regelmäßig: kleinere Denk- und Programmier-Aufgaben,
Kontrolle mündlich im Seminar/Pool oder automatisch
(Web-Interface, siehe oben).
• schließlich: Prüfungs-Klausur
Was ist Informatik
(vgl. Kapitel 1 aus Horn/Kerner/Forbig)
Wissenschaft von der Informationsverarbeitung
junge Wissenschaft mit alten Inhalten (Tabelle S. 21)
drei Typen von Maschinen (Tabelle S. 22)
Defn. Algorithmus (Seite 22)
Computer als Werkzeug (Seite 27f.) Beispiel: Simulation
(Wettervorhersage)
Geschichte
(HKF 1.4)
Entwicklung der Mathematik (irdische und astronomische
Geometrie, Messungen von Weg und Zeit)
Rechenvorschriften (schriftl. Multiplikation), Tafeln von
Logarithmen, Winkelfunktionen
maschinelle Hilfen bei deren Berechnung (Babbage),
programmgesteuerte Webstühle (Jacquard),
Lochkartenzählmaschinen
frei programmierbare Maschinen (Zuse ab 1936)
prinzipielle Grenzen von Algorithmen (Gödel 1931, Turing
1936)
Computer-Architektur nach von Neumann
frei adressierbarer Hauptspeicher, zur Erleichterung
verwende nicht Adressen, sondern Namen.
Programm-zustand ist Speicherinhalt (= Abbildung von
Adressen auf Werte)
Und: Programm steht selbst im Speicher.
• Zuweisungen: Name := Ausdruck
• wobei Ausdruck: Konstante oder Name oder Operator
mit Argumenten
• wobei Argument: Konstante oder Name
• Sprünge (unbedingte und bedingte)
Übung: was ändert sich, wenn man als Argument auch
Ausdrücke gestattet?
Strukturiertes Programmieren
Programm-Ablauf-Steuerung nicht durch Sprünge,
sondern durch hierarchische Struktur.
• Blöcke (Anweisungsfolgen)
• Verzweigungen (if then else)
• Wiederholungen (while)
• Unterprogramme (benannte Blöcke)
Jeder dieser Bausteine hat genau einen Eingang und
genau einen Ausgang.
Einfache (?) Algorithmen
a := a + b ; b := a - b ; a := a - b;
Collatz-Problem: Hält dieser Algorithmus für jede Eingabe
≥ 1?
Eingabe x;
solange (x > 1)
wenn x eine gerade Zahl ist,
dann x := x / 2 sonst x := 3 x + 1
Übung: finden Sie Startwerte, für die der Algorithmus
ziemlich lange rechnet.
Sortier-Algorithmen
Eingabe: eine Folge (x1, x2, . . . , xn) von Zahlen.
Ausgabe: eine Folge (y1, y2, . . . , yn) von Zahlen.
Bedingungen:
• die Ausgabe ist eine Permutaion (= Umordnung) der
Eingabe.
• die Ausgabe ist aufsteigend geordnet.
Einfacher Algorithmus: Sortieren durch Einfügen. In
Seminaren mehr dazu.
Sortiernetze
Algorithmen “in Hardware”: Komparatoren.
Bubblesort-Netzwerk. In Seminaren: Korrektheit.
Aufgabe: Finde Sortier-Netzwerk für 4 Elemente mit 5
Komparatoren. Wieviele brauchen Sie für 5?
In Seminaren: Odd-Even-Sort für 8.
danach Übung: wie geht das für 16? Warum stimmt es?
Seminare
Wiederholung zur Vorlesung (Defn. Informatik,
Algorithmus)
Einfache Sortiernetze: 4 Eingänge mit 6, mit 5
Komparatoren.
Beweis, daß 4 Komparatoren nicht ausreichen. Dazu:
Anzahl der Permutationen von n Elementen ausrechnen.
Schubfachschluß wiederholen.
Später: Sortiernetze für 5 (6,7,8,9) Eingänge als
autotool-Aufgabe.
Bubblesort als Netz, induktive Definition. → als Programm.
Geschachtelte Schleifen. Ausführung simulieren.
Sortieren mit möglichst wenig Vergleichen (5 Elem. mit 7
Vgl., weniger geht nicht)
Median von 5 mit 6 Vergleichen (d. h. weniger als
Sortieren)
Berechenbarkeit, Komplexität (24. 10.
03)
Literatur: Horn/Kerner Kap. 8.3 (Komplexität), Kap. 8.2
(Berechenbarkeit)
Komplexität von Algorithmen
Wie gut ist ein Algorithmus?
• Wieviel Rechenzeit/Speicherplatz benötigt er?
• Für eine spezielle Eingabe? — Besser: Mengen von
ähnlichen (= gleich großen) Eingaben betrachten.
• Resourcenverbrauch im besten, mittleren, schlechtesten
Fall.
• Betrachten der Verbrauchsfunktion (bildet Eingabegröße
auf Kosten ab).
• Maschinen-unabhängige Aussagen durch Betrachtung
des (asymptotischen) Wachstums, d. h. ignoriere:
– Unregelmäßigkeiten für kleine Eingaben
– konstante Faktoren (für alle Eingaben)
Komplexität – Beispiel
Sortieren durch lineares Einfügen (Bubblesort, bzw.
entsprechendes Netzwerk) benötigt für n Elemente
0 + 1 + 2 + . . . + (n − 1) = (n − 1)n/2
Vergleiche.
Egal, auf welchem Rechner wir das ausführen, die Laufzeit
wird immer eine quadratische Funktion der Eingabegröße
sein.
D. h. Eingabegröße verdoppeln → vierfache Laufzeit,
verdreifachen → neunfache, usw.
Schnelleren Prozessor kaufen lohnt sich kaum, man
gewinnt damit nur einen konstanten Faktor. Viel wirksamer
sind bessere Algorithmen!
Merge-Sort (Sort)
sortiere (a) =
wenn Länge (a) <= 1,
dann gib a aus,
sonst
setze
b = (ungefähr) die Hälfte
der Elemente von a;
c = die restlichen Elemente von a;
b’ = sortiere (b)
c’ = sortiere (c);
füge b’ und c’ zusammen;
die Ausgabe von sortiere(a) enthält alle Element von a
genau einmal und ist aufsteigend geordnet.
Entwurfsprinzip: Rekursion, Teile und Herrsche (divide and
conquer)
Merge-Sort (Merge)
b’ und c’ sind Listen von Elementen (Zahlen)
füge b’ und c’ zusammen =
solange ( b’ nicht leer und c’ nicht leer
wenn erstes (b’) < erstes (c’)
dann ausgabe(erstes (b’)); verkürze b
sonst ausgabe(erstes (c’)); verkürze c
gib restliche Elemente von b’ aus
gib restliche Elemente von c’ aus
in der Ausgabe stehen alle Element von b’ und c’ genau
einmal.
Der Algorithmus erfüllt einen Vertrag:
wenn b’ und c’ zu Beginn aufsteigend geordnet sind, dann
ist die Ausgabe aufsteigend geordnet.
Anzahl der Vergleiche ist ≤ Länge von b + Länge von c −
1
Merge-Sort (Komplexität)
Anzahl der Vergleiche?
T (1) = 0, T (n) = T (bn/2c) + T (dn/2e) + (n − 1)
Beispiele:
n 1 2 3 4 5 6 7 8 9
T (n) 0 1 3 5 8 11 14 17 21
Übung: beweise durch Induktion T (2k ) = 1 + (k − 1) · 2k .
Mit n = 2k , also k = log2 n folgt T (n) ≈ n log2 n.
D. h. Merge-Sort ist asymptotisch besser als Bubble-Sort.
Komplexität von Problemen
Wie schwer ist ein (algorithmisches) Problem?
Wieviel Ressourcen braucht jeder Algorithmus, der das
Problem löst?
(Bereits gezeigt) Für jedes Sortierververfahren für n
Elemente gibt es eine Eingabe, für die das Verfahren
≥ log2(n!) Vergleiche ausführt.
Übung: log2(n!) ≈ n log n
Folgerung: Sortieren hat eine Komplexität von wenigstens
n log n. (D. h. mehr als linear.)
Folgerung: Merge-Sort ist optimal (Bubble-Sort nicht).
Schwere Probleme
Es gibt Aufgaben, deren Lösung exponentiell lang ist.
Beispiel: Türme von Hanoi. n Scheiben mit Durchmessern
1, 2, . . . , n liegen übereinander auf einem Turm A (in einem
Kloster in Hanoi, jedenfalls der Sage nach). Sie sollen
einzeln auf einen Turm B bewegt werden, allerdings darf
nie eine größere über einer kleineren Scheibe liegen. Es
darf ein Hilfsturm C benutzt werden.
Scheibe n (die größte) muß sich irgendwann einmal
bewegen (da sie anfangs auf A liegt, aber schließlich auf
B sein muß). Im besten Fall bewegt sie sich genau einmal.
Zu diesem Zeitpunkt müssen alle anderen Scheiben auf C
liegen! Wie kommen sie dorthin? Das ist eine (um eine
Scheibe) verkleinerte Version der selben Aufgabe!
Hanoi (2)
Also ist das die optimale Lösung:
move (k, v, n, h) =
-- hier gilt: Scheiben 1, 2 .. k
-- liegen oben auf v (andere Scheiben eg
falls (k > 0), dann
move (k-1, von, hilf, nach)
lege Scheibe k von v nach n
move (k-1, hilf, von, nach)
-- hier gilt: Scheiben 1, 2 .. k
- liegen oben auf n
-(andere Scheiben wurden nicht bew
und für k Scheiben braucht man 2k − 1 Züge.
n
5 10 15 20 25 30 50 100
H(n) 31 1023 104 106 107 109 1015 1030
Suchprobleme
Viele Aufgaben lassen sich als Such-Probleme
formulieren.
Beispiel 1 (COL): gegeben sind ein Netzplan (ein Graph,
bestehend aus Knoten und Kanten) sowie eine Zahl c von
Farben. gesucht ist eine Färbung der Knoten, so daß keine
Kante zwischen gleichfarbigen Knoten verläuft.
(nicht in Vorlesung), Beispiel 2 (Lunar Lockout, siehe
www.binaryarts.com): gegeben ist eine Anordnung von
Robotern. Gesucht ist eine Folge von (erlaubten)
Bewegungen, nach der schließlich der rote Roboter in der
Mitte steht.
Suchprobleme (2)
Bei COL und LL sind die Suchräume beschränkt: es gibt
nur |Knoten||Farben| verschiedene Färbungen, bzw. nur
|Spielfelder||Roboter| verschiedene Anordnungen.
Schlimmstenfalls probiert man alles durch.
Der Unterschied ist jedoch, daß man für eine Färbung sehr
schnell (in polynomieller Zeit) prüfen kann, ob sie eine
Lösung ist;
aber eine Anordnung von Robotern allein noch keine
Lösung ist; man muß alle Folgen untersuchen. Da nur
wiederholungsfreie Folgen interessant sind, sind es
trotzdem nur endlich viele.
Suchprobleme (3)
Beispiel 3 (PCP): Gegeben ist eine Liste von Wort-Paaren.
Gesucht ist eine Folge (von Kopien dieser Paare), bei der
die Verkettung alle linken Seiten das gleiche Wort ergibt
wie die Verkettung aller rechten Seiten.
110 0 1
001 0 1
Beispiele:
Das linke hat
1 1 01
0 1 001
kürzeste Lösung AACBCCBC. Aufgabe: finde Lösung für
das rechte (es gibt eine).
Jetzt ist der Suchraum (alle Folgen) gar nicht beschränkt
(die Folgen können beliebig lang sein).
Tatsächlich ist PCP algorithmisch unlösbar ! (Es gibt keinen
Algorithmus, der für jede Liste von Paaren korrekt
entscheidet, ob die Aufgabe eine Lösungsfolge besitzt.)
Algorithmisch unlösbare Probleme (1)
Da Algorithmen beschreibungs-endlich sind, können wir
sie auch durchnumerieren. Z. B. Java-Quelltexte erst der
Länge nach und innerhalb der Länge alphabetisch. Die
syntax- und typ-fehlerbehafteten Texte streichen wir, übrig
bleibt eine Anordnung P0, P1, . . . aller tatsächlich kompilierund ausführbaren Programm-Texte.
Algorithmisch unlösbare Probleme (2)
Das Halteproblem ist:
• Eingabe: ein Zahl x und eine Zahl y
• Frage: hält das Programm Px bei Eingabe y?
Wir beweisen, daß das algorithmisch unlösbar ist: es gibt
keinen Algorithmus, der die Frage für alle Eingaben korrekt
beantwortet.
Algorithmisch unlösbare Probleme (3)
Indirekter Beweis: Falls das Halteproblem doch
algorithmisch lösbar ist:
Dann definieren wir das Programm H : x 7→ falls Px(x)
(Das Programm mit Nummer x, gestartet mit Eingabe x)
hält, dann irgendeine nicht haltende Rechnung (Schleife),
sonst 0.
Das Programm H hat auch eine Nummer, diese sei n. Also
H = Pn .
Hält H(n)? Wegen der Fallunterscheidung gilt H(n) hält
⇐⇒ H(n) = 0 ⇐⇒ Pn(n) hält nicht ⇐⇒ H(n) hält nicht!
Das ist ein Widerspruch, d. h. (wenigstens) eine Annahme
war falsch: H ist gar nicht programmierbar!
Vergleich von Problemen
Man kann Schwierigkeit von Problemen untereinander
vergleichen.
Definition: P1 ≤ P2 falls es eine (wenig aufwendige)
Funktion f gibt, so daß für alle x gilt: x ist Lösung von P1
⇐⇒ f (x) ist Lösung von P2.
Wenn P1 ≤ P2 und P2 (leicht) lösbar, dann auch P1 (leicht)
lösbar.
Man kann zeigen: Halteproblem ≤ PCP.
Nach Kontraposition (Umkehrschluß) folgt: Halteproblem
algorithmisch unlösbar ⇒ PCP algorithmisch unlösbar.
Indiz: sehr kleine und trotzdem schwere PCP-Instanzen (d.
h. mit sehr langer Lösung).
Grundlagen der
Java-Programmierung (Seminar 7. 11.
03)
Objekte
objektorientierte Spache Java.
Ein Objekt besitzt Attribute und ist Instanz einer Klasse.
Eine Klasse beschreibt eine Gesamtheit von Objekten
durch Deklarationen von Attributen und Methoden, das
sind Unterprogramme.
Ein Software-Projekt besteht aus einer Gesamtheit von
Klassen.
Programmieren mit BlueJ
wir benutzen Integrierte Entwicklungsumgebung BlueJ,
http://www.bluej.org
enthält Projekt-Manager, Editor, (Verweis auf) Compiler,
Debugger, Objekt-Inspektor.
(d. h. JDK braucht man extra, http://java.sun.com)
Wir beginnen mit einfachen Übungen zu
Programmstrukturen und ignorieren dafür zunächst alles,
was speziell mit Objektorientierung zu tun hat.
(für die Auskenner: deswegen sind zunächst alle unsere
Methoden static.)
Einfach anfangen
• BlueJ-Symbol (Vogelkopf) clicken, JDK suchen
• Project -¿ New Project (Namen aussuchen)
• New Class (Namen aussuchen, z. B. Maxi)
• Doppel?Click auf Maxi-Symbol, Editor geht auf
• neue Methode eingeben
static int maximum (int a, int b) {
if ( a > b ) { return a;
} else { return b; }
}
• Compile
• Rechts-Click auf Maxi-Symbol, Methode maximum
auswählen
• zwei Parameter eingeben, Resultat ansehen.
Aufgabe: Median
implementiere eine Methode
static int median (int a, int b, int c) {...
}
sie soll das mittlere der drei Argumente zurückgeben.
Benutzen Sie nur (geschachtelte) Verzweigungen und
return (keine Zuweisungen).
Zusatz: implementieren Sie Median von fünf Elementen.
Sie dürfen Verzweigungen und Zuweisungen benutzen
(jedoch keine Schleifen).
Programm für Türme von Hanoi
Vgl. Vorlesung. Implementiere die Prozedur move!
static void move
(int k, int von, int nach, int hilf) { .
Um die Bewegung auszugeben, benutzen Sie
System.out.println ("Scheibe " + k
+ " von " + von + " nach " + nach );
Bastelaufgabe: Wie schnell geht es, wenn man nicht
einen, sondern zwei Hilfstürme benutzen darf? Wie sieht
der optimale Algorithmus aus? Wieviele Züge brauchen sie
für 5,7,10 Scheiben?
(evtl. autotool.)
Die Collatz-Folge
(Siehe Vorlesung.) Schreiben Sie eine Methode, die für
gegebenen Startwert die Folge berechnet und druckt
sowie die Länge der Folge zurückgibt.
Den Rest bei Division durch 2 bestimmen Sie so: x % 2,
den (abgerundeten) Quotienten so: x / 2.
static int count (int x) {
int c = 0;
while ( ... ) {
System.out.print (x + " ");
if ( ... ) { ... } else { ... }
}
return c;
}
Collatz (2)
Zusatz: Rufen Sie diese Methode wiederholt auf (für
Argumente 1,2,3,. . . ) und geben Sie jeweils neue
Rekord-Folgen-Längen aus.
static void tops () {
int top = 0;
for (int x=0; x < 1000000 ; x++) { ..
}
Grundlagen der
Java-Programmierung (Vorlesung 7.
11.)
Dokumenationen und Anleitungen zu Java finden Sie hier:
http://developer.java.sun.com/developer/
infodocs/
Typen und Ausdrücke
Datentypen
Literatur: Vergleiche HKF Kapitel 4.3
Nach dem von-Neumann-Modell besteht der Speicher aus
Zellen mit jeweils Adresse und Wert.
In einer typisierten Sprache gehört jeder Wert
(Zellen-Inhalt) zu einem Datentyp.
Ein Datentyp besteht aus:
• Bereich der zugelassenen Werte
• Beschreibung der zugelassenen Operationen
(Unterprogramme)
Arten von Datentypen
• elementare Typen:
– (nicht zu große) ganze Zahlen: int
– Zeichen: char
– Wahrheitswerte: boolean
• zusammengesetzte Typen:
– Zeichenketten: String
– Felder (Arrays), Objekte/Klassen (später)
wo werden Typen definiert?
• gehören zur Sprache (int, . . . )
• zu Bibliotheken: Applet, Button, ..
• sind selbst definiert (Klassen)
Deklarationen von Variablen
• Form: Typ, Name, Semikolon, Bsp: int x;
• Sichtbarkeit: Name kann verwendet werden . . .
– im direkt umgebenden Block nach Deklaration bis }
– ebenso in allen Unterblöcken in diesem Bereich
– sofern nicht verdeckt durch weiter innen deklarierte
gleich benannte Variable
Mögliche Fehler:
•
•
•
•
Deklaration einer Variablen vergessen
Variable vor Deklaration benutzt
Variable in einem Block mehrfach deklariert
unabsichtlich durch innere Deklaration Namen verdeckt
Typ-Prüfungen
Name bezeichnet zu jeder Zeit einen Wert vom
deklarierten Typ. Falls nicht, dann durch Fehler im
Programm. So früh wie möglich feststellen! (umso geringer
sind die Kosten)
• (gar nicht: Zentimeter und Zoll addiert, Mars-Sonde
abgestürzt)
• vor Ausführen von Operationen (nur typreine Addition)
• bereits beim Zuweisen an Variablen Typ prüfen
• statische Typ-Prüfung: nicht erst bei Ausführung,
sondern vorher (beim Kompilieren)
Nutzen: nicht nur Sicherheit, sondern Effizienz
(vollständige statische Prüfung: keine dynamische Prüfung
nötig)
Ausdrücke
Ausdrücke beschreiben Werte eines bestimmten Typs.
• einfache Ausdrücke:
– Konstanten (Zahlen, Zeichen, Strings, Wahrheitswerte)
– Namen (als Verweis auf eine Speicherstelle)
• zusammengesetzte Ausdrücke:
– Funktionsaufruf: Name, Liste von Ausdrücken
– Operator-Aufruf: Ausdruck, Operator, Ausdruck
Bei zusammengesetzten Ausdrücken müssen die Typen
aller Teilausdrücke zusammenpassen (Übungen!).
Dazu muß man die Typen den Namen (Variablen) sowie
der benutzen Funktionen und Operatoren kennen
(Beispiele!)
Ausdrücke und Typen – Aufgaben
int (operator +) (int x, int y);
boolean (operator <) (int x, int y);
boolean (operator &&) (boolean x, boolean y)
int min2 (int x, int y);
int fun (t1 x, t2 y);
p < (q < r)
(p < q) && (q < r)
min2 (min2 (1, a), b)
fun (fun (c, d), c)
Anweisungen
Unterprogramme
• Funktion (gibt Wert zurück, ist (Teil eines) Ausdrucks)
• Prozedur (gibt keinen Wert zurück, ist Anweisung)
Beispiel:
public static int quad (int x) { int y; retu
Bestandteile:
• Kopf: (Eigenschaften), Ergebnistyp, Name, formale
Parameter
bei Prozedur ist Ergebnistyp void
• Körper: ein Block
Blöcke
Ein Block ist eine (beliebig gemischte) Folge von
Deklarationen und Anweisungen, die durch { und }
eingeschlossen wird.
TIP: wenn Sie eine öffnende Klammer tippen, tippen Sie
sofort die entsprechende schließende Klammer dazu, und
füllen Sie das Innere später.
Anweisungen (elementare)
• Zuweisung: Name = Ausdruck
• Methoden-Aufruf: Name, Liste von Ausdrücken
• Rückkehr aus Prozedur: return
• Rückkehr aus Funktion: return Ausdruck
Beachte: wird durch Semikolon abgeschlossen.
Typen müssen passen (was bedeutet das im Einzelnen)?
Anweisungen (zusammengesetzte)
• Verzweigung: if ( Ausdruck ) Block ( else Block )
• Schleife: while ( Ausdruck ) Block
Ausdrücke müssen vom Typ boolean sein.
Für die Blöcke Hinweis zum Klammernschreiben beachten!
Klassen
(vereinfachte Version, für den Moment)
eine Klasse besteht aus Namen und einem Block, in dem
nur static-Variablen und static-Methoden deklariert
werden dürfen.
(D. h. Anweisungen selbst gibt es dort nicht — wohl aber
innerhalb der Blöcke, die zu den Methoden gehören).
Entwurfsregeln
Programm-Design
Algorithmus in Unterprogramme zerteilen, die man einzeln
verstehen, testen, benutzen kann.
Jedes Unterprogramm kommentieren. (Kommentar: von
// bis Zeilenende)
Welchen Vertrag erfüllt das Unterprogramm?
• Welche Eingaben erwartet es,
• was ist die Wirkung der Prozedur,
• bzw. was der Wert der Funktion?
Programm-Layout
Jedes Unterprogramm kürzer als eine Bildschirmseite!
Struktur des Algorithmus (= Schachtelung der Blöcke) soll
optisch deutlich werden.
In einem Block: jede Anweisung/Deklaration auf neuer
Zeile, in gleicher Spalte beginnend.
Bei Unter-Block weiter einrücken.
schließende Klammer . . .
unter Block-Anfang
unter öffnender Klammer:
if (a > b) {
if (a > b)
return a;
{
}
return a;
(spart eine Zeile)
}
Ergänzungen
Zählschleifen
Typische Schleife:
for (int i = a; i < b; i++) {
System.out.println (i);
}
ist äquivalent zu
{ int i = a;
while (i < b) {
System.out.println (i);
i = i + 1;
}
}
Beachte: Bedingung wird jedesmal ausgewertet,
Laufvariable ist nur in der Schleife sichtbar.
Felder (Arrays)
Feld = Folge von Speicherzellen gleichen Typs, durch
Zahlen (Indizes, Offsets) adressiert.
• Deklaration/Initialisierung:
int [] a = { 4, 1, 5, 2, 3 };
• Zugriff (Lesen/Schreiben):
int i = 3; a [i] = a [i + 1];
Vorsicht: Index-Zählung beginnt bei 0.
• Länge: a.length
Zugriff außerhalb von a [0 .. a.length-1] ist Fehler.
Beispiele
Bubble-Sort
static void swap (int [] a, int x, int y) {
// vertausche a[x] mit a[y]
int h = a[x];
a[x] = a[y]; a[y]=h;
}
static void bubble (int [] a, int x, int y)
// stellt a[x] <= a[y] her
if (a[x] > a[y]) {
swap (a, x, y);
}
}
Bubble-Sort (II)
static void bubble_sort (int [] a) {
// sortiert a aufsteigend
for (int i=0; i<a.length; i++) {
// füge a[i] in bereits
// sortiertes a[0 .. i-1] ein
for (int j=i-1; j >= 0; j--) {
bubble (a, j, j+1);
}
}
}
static void check () {
int a [] = { 0,5,3,1,4,2 };
println (a); bubble_sort (a); printl
}
Quick-Sort
Ein weiteres Sortierverfahren
nach dem Prinzip teile und herrsche
sortiere (a [lo .. hi]) =
falls ( lo < hi ), dann
permutiere Elemente so,
daß es ein m gibt mit:
für jedes x in a [lo .. m ]
und jedes y in a [m+1 .. hi]
gilt x <= y
sortiere (a [lo .. m ]);
sortiere (a [m+1 .. hi]);
Quicksort (II)
Wie erreicht man die Verteilung?
Wähle ein p und bewege:
alle x in a [lo .. hi] mit x < p nach links,
alle x in a [lo .. hi] mit x > p nach rechts.
Ansatz:
int p = a [lo]; int l = lo; int r = hi;
while (l < r) {
while ( a[l] <= p ) { l++; }
while ( a[r] >= p ) { r--; }
if (l < r) { swap (a, l, r); }
}
Aufgabe: finde Fehler und repariere!
Quicksort (III)
Vorteile:
• Wenn p immer nahe beim Median, dann schnelles
Sortieren (asymptotisch wie bei Merge-Sort, Θ(n log n))
• Dann sogar (um konstanten Faktor) besser als
Merge-Sort, weil Elemente in ihren Bereichen verbleiben.
Nachteile:
• nur wenige Zeilen, aber viele Fehlermöglichkeiten!
• Wenn p schlecht gewählt, dann langsames Sortieren
(wie Bubble-Sort, Θ(n2), für sortierte Eingaben)
• möglicher Ausweg: p = a [zufällig];
Übung am 14. 11.
Übung (14. 11.)
Kontrollfragen aus HKF Abschnitt 4.1.6 (Struktur-Elemente
von Algorithmen)
Lunar Lockout as Suchproblem. Aufgabe: wie groß ist der
Suchraum?
Wiederholung Merge-Sort
evtl. Bemerkungen zu Sortier/Merge-Netzen
(autotool-Aufgaben)
Quicksort: Korrektheit der inneren Schleife, Laufzeit.
Lunar Lockout
autotool:
Robots-R-{Alex,Fourty}
Die Großbuchstaben bezeichnen
die Roboter. Die Aufgabe ist, A auf
die (anfangs leere) Position a zu bewegen.
Roboter fahren geradlinig, ohne
Bremse, bis zu Hindernis.
B
.
.
.
.
.
.
.
.
G
.
D
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
E
.
.
.
.
a
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
C
.
.
.
.
.
.
.
.
A
.
.
.
.
.
.
.
.
F
http://www.thinkfun.com/buy/games/
lunarLockout.html
Ähnliches Spiel: Ricochet Robot (Rasende Roboter) von
Alex Randolph, http://sunsite.informatik.
rwth-aachen.de/keirat/txt/R/Rasenrob.html
Ergänzungen (21. 11. 03)
Ergänzungen zu Kontrollstrukturen
Literatur: HKF Kapitel 5.4
Schleifen-Invarianten
static int power (int b, int e) {
int p = 1; int q = b;
while (e > 0) {
if (1 == e % 2) { p = p * q; }
q = q * q; e = e / 2;
}
return p;
}
Der Ausdruck A = p · q e ist invariant:
seine Werte vor und nach Ausführen eines
Schleifenkörpers stimmen überein.
Invarianten (II)
Beweis: Falls e > 0 und e gerade, dann
p0 = p, q 0 = q 2, e0 = e/2, also p0 · q 02 = p · q 2·e/2 = p · q e.
Falls e > 0 und e ungerade: Übung.
Der Wert von A vor der Schleife ist 1 · be,
der Wert von A nach der Schleife ist p · q 0 = p.
Invarianten (III)
Denken Sie zuerst an die Invariante, und notieren Sie sie
(als Kommentar zu Beginn der Schleife).
Schreiben Sie dann den Schleifenkörper so, daß die
behauptete Invariante tatsächlich invariant ist.
Für Sonderformen von Schleifen (do-while, break) ist diese
Analyse viel schwieriger, deswegen sollten diese auch
nicht ohne besonderen Grund benutzt werden.
Mehrfach-Verzweigungen
int h = n;
if (h == 1) {
switch (n) {
case (1) :
Block-A;
{ Block-A; break; } } else {
if (h == 2) {
case (2) :
Block-B;
{ Block-B; break; }
default :
} else {
Block-C;
{ Block-C; }
}
}
}
Beachte: break aus historischen Gründen (C) nötig
Vorteile: übersichtlicher und effizienter (Sprungtabellen)
Übung: wieso wird rechts neue Variable h benutzt?
Weitere Formen von Schleifen
Schleife mit nachgestelltem Test:
do { B; } while ( A );
Aufgabe: finde äquivalentes Programm mit while-do.
Vorzeitiges Verlassen/Wiederholen einer Schleife:
while ( B1 ) {
A1;
if ( B2 ) { break; }
A2;
if ( B3 ) { continue; }
A3;
}
Aufgabe: finde äquivalente while-Schleife (ohne break,
continue). (benutze Hilfsvariable boolean c2, ..)
Ergänzungen zu Unterprogrammen
Argument-Übergabe für Unterprogramme
Deklaration:
T1 fun (T2 x) { Block; }
Aufruf:
.. fun (A1) ..
• call-by-value (Übergabe als Wert):
vor Block x mit Wert von A1 initialisieren.
• call-by-reference (Übergabe als Verweis):
A1 bezeichnet ein Objekt, in Block bezeichnet x
dasselbe Objekt wie A1.
• call-by-name (Übergabe als Name):
in Block wird x überall durch A1 ersetzt.
Argument-Übergabe (Beispiele)
Deklaration:
static void p (int x)
{ print (x);
x ++;
}
Deklaration:
static void swap
(int [] f,
int i, int j)
{ int h = f [i];
f [i] = f [j];
f [j] = h;
}
Aufruf:
int a = 5;
print (a);
p (a);
print (a);
Aufruf:
int [] a
{ 2,
print (a
swap (a,
print (a
=
4, 1 };
[0]);
0, 1);
[0]);
Argument-Übergabe in Java
• call-by-value für elementare Typen
(int, char, boolean, ..)
• call-by-reference für zusammengesetzte Typen (Objekte,
einschl. Felder und Strings)
Parameter-Übergabe (Eigenschaften)
• call-by-value:
Vorteil: leicht zu verstehen, zu analysieren
Nachteil: Kopieren von zusammenges. Werten teuer
• call-by-reference:
Vorteil: kein Kopieren nötig
Nachteil: nicht-lokale Änderungen schwerer zu verstehen
• call-by-name:
Vorteil: in einigen Spezialfällen einzig mögliche Lösung
Nachteil: nicht effizient (evtl. mehrfache Auswertung),
undurchschaubare Effekte (siehe Beispiel)
Aufgabe zu Call-by-Name
static void tausche (int x, int y) {
int h = x; x = y; y = h;
}
Hat das unter Call-by-Name tatsächlich die gewünschte
Wirkung?
Nein! Betrachte
int a [] = { 3, 1, 4, 6 }; int i = 2;
tausche (i, a [i]);
Übung 24. 11.
Sortieren/Aufgaben
Bubble-Sort: Code vervollständigen, ausprobieren
Quick-Sort: Code vervollständigen, ausprobieren
http:
//www.imn.htwk-leipzig.de/˜waldmann/ws03/
informatik/programme/sortier/Sortier.java
BlueJ-Debugger
Kompilieren, im Editor-Fenster Breakpoint setzen
(Control-B), im Projekt-Fenster Methode aufrufen, bei
Erreichen des Breakpoints erscheint Debugger-Fenster.
Step: nächste Zeile ausführen (d. h. Ausführung von
Unterprogrammen nicht anzeigen),
Step Into: Unterprogramme auch anzeigen.
Aktuelle Zeile ist im Editor-Fenster markiert.
Objekt-Orientiertes Programmieren
(21. 11. 03)
Literatur: HKF Kapitel 5.4 (ab S. 291)
Objekte, Methoden
Daten sind passiv (man kann sie nur lesen/schreiben).
Operationen mit Daten durch Unterprogramme.
Entwurfsziel: Daten und passende Operationen verbinden.
Aus Daten werden Objekte:
Definition: ein Objekt besteht aus
• Attributen (Daten)
• Methoden (Unterprogrammen)
Klassen
Definition: Eine Klasse beschreibt gleichartige Objekte
(gleiche Namen und Typen für Attribute und Methoden).
Definition einer Klasse:
Objekt deklarieren, initiapublic class Counter
lisieren, Methoden aufru{
fen, Attribut lesen:
int ticks;
{ Counter c =
void reset ()
new Counter ();
{ ticks = 0; }
c.reset (); c.step
void step ()
System.out.println
{ ticks ++ ; }
(c.ticks);
}
}
• Attribut: Objektname . A.-Name
• Methoden-Aufruf: Objektname . M.-Name Argumentliste
Objekte in Bluej
Rechts-Klick auf Klassen-Symbol zeigt Konstruktor
new Name ().
Klick darauf legt neues Objekt an, erscheint als (rotes)
Symbol.
Rechts-Klick auf Objekt-Symbol zeigt Methoden (Click auf
Methode ruft auf).
Click auf inspect zeigt Attribute.
Lebenslauf eines Objekts
• (Deklaration) Counter c;
• Konstruktion/Initialisierung c = new Counter ();
• Leben “
”
• Finalisierung (erfolgt automatisch)
Ein Objekt wird durch Aufruf eines Konstruktors hergestellt
(Form: new Klassenname);
Dabei Attribute initialisiert (falls so deklariert)
(int click = 0;)
Konstruktoren
Eigene Konstruktoren sind möglich (auch überladene).
public Counter (int x) { click = x; }
...
Counter c = new Counter (3);
Konstruktor-Methode ist Funktion ohne Namen,
Ergebnistyp ist die Klasse.
Überladen von Namen
Ein einziger Name kann verschiedene Methoden
bezeichnen, falls man sie anhand der Argumentliste
(Länge und Typen) unterscheiden kann.
public class C {
void p () { ... }
void p (int x) { ... }
}
Beachte: Überladung mit gleichen Argument-Typen und
verschiedenen Ergebnis-Typen ist nicht erlaubt.
Aufgaben: kann man Prozedur durch Funktion überladen?
Methode durch Attribut?
Statik und Dynamik
solange nichts anderes deklariert ist, gehören jedes
Attribut und jede Methoden zu einem Objekt:
• jedes Objekt hat seinen eigenen Speicherplatz für
Attribute
• Benutzung/Aufruf ist nur über Objektnamen möglich
Durch Deklaration static: Attribute/Methoden gehören
zur Klasse (und nicht zu einem einzelnem Objekt).
Benutzung über Klassen- (nicht: Objekt-)Namen. Bsp:
int x = Integer.parseInt ("123");
In statischen Methoden sind nur statische Attribute und
Methoden benutzbar (warum?)
Zeichenketten
vordefinierte Klasse String
String s = "foobar";
int l = s.length (); // 6
char c = s.charAt (3); // ’b’
String t = s.substring (1, 3); // "oob"
Bemerkungen:
• Jedes Objekt besitzt Methode String toString ().
• Operator + erzeugt Verkettung von zwei Strings.
• Wenn ein nur ein Argument von + ein String ist, dann
wird auf den anderen toString() angewendet.
Beispiel: System.out.println ("x = " + x);
Strings (Aufgabe)
implementieren Sie einen Test
static boolean palindrom (String s)
so daß palindrom ("reliefpfeiler") = true.
Benutzen Sie s.length(), s.charAt(..), while.
Suchen Sie damit eine Zahl n, die keine Palindrom ist,
aber deren Quadrat doch. Bsp: 7986442 = 637832238736.
(Gibt es unendlich viele solche Zahlen?)
(desgl. für dritte Potenz)
Hinweis: benutzen Sie nicht int n, sondern long n,
sowie Long.toString (n).
Weitere Aufgabe zu Palindromen
Hält das folgende Programm immer?
while ( x ist kein Palindrom ) {
x = x + Spiegelzahl von x;
}
Beispiel: 199, 1190, 2101, 3113.
Überprüfen Sie alle Start-Zahlen ≤ 1000.
Klassen, Vererbung, Interfaces (5. 12.)
Beziehungen zwischen Klassen
class C {
D ist abgeleitet von C
int a;
(oder: D erweitert C)
void m () { ... }
D besitzt
}
• alle Attribute und Methoden class D extends C {
von D
int b;
void p () { ... }
• und weitere, eigene.
}
Beispiele:
• Basis: Zähler mit step, abgeleitet: . . . und reset
• Basis: Grafik-Element, abgeleitet: . . . mit Farbe
Grundsatz: überall, wo Objekte der Basisklasse stehen,
dürfen auch Objekte davon abgeleiteter Klassen stehen.
Überschreiben von Methoden
Abgeleitete Klassen können Methoden der Basisklasse
neu implementieren (überschreiben).
class C {
class D extends C {
int a;
void m () { ... }
void m () { ... }
}
}
Es wird immer die speziellste Methode benutzt:
C x; x.m (); D y; y.m ();
Wichtig: das Überschreiben nicht verwechseln mit dem
Überladen!
Objektorientierung (Überblick)
OO =
• Objekte mit Attributen und Methoden,
• Beziehungen: Vererben und Überschreiben.
• Simula 68 (Ole-Johan Dahl, Kristen Nygard)
(Prozess-Simulation) Coroutinen, Klassen, Objekte
• Smalltalk http://www.smalltalk.org,
(Adele Goldberg, Alan Kay, Xerox Parc, ab 1972)
(Grafische Nutzeroberflächen)
• C with Classes, C++ (Bjarne Stroustrup, ab 1980)
• Java (James Gosling, 1995) http://java.sun.com/
features/1998/05/birthday.html
(Grafik, Kommunikation, für mobile Endgeräte)
Objektorientierte Analyse/Modellierung
nicht nur Programme, sondern (technische) Systeme
beschreiben:
• Komponenten (Objekte),
• Eigenschaften (Attribute, Methoden)
• Gemeinsamkeiten (Klassen)
• Hierarchien (Vererbung)
dafür gibt es standardisierte Verfahren, Werkzeuge und
Sprachen (UML).
automatische Unterstützung von OO-Programmierung
durch Generierung von Programmtexten (-Bausteinen).
Vererbung: Vor/Nachteile
• Vorteil: Nachnutzung von Programmen
• Nachteil: abgeleitete Klasse sieht alle Details der
Basisklasse
verletzt das Prinzip des information hiding: so wenig wie
nötig interne Klassen-Informationen nach außen geben,
damit nachträglich Implementierung verbessert oder
ausgetauscht werden kann.
Für größere Projekte: Modularisierung und Information
Hiding durch andere Techniken erzwingen (OO kann das
gar nicht alles leisten)
Abstrakte Methoden und Klassen
abstract class C {
void p () { .. } ; abstract void m ();
}
class D extents C { void m () { .. } }
abstrakte Methoden sind in Basisklasse deklariert, (aber
nicht implementiert), müssen in abgeleiteten Klassen
implementiert werden.
Basisklasse muß als abstract deklariert werden.
Schnittstellen (Interfaces)
Schnitstelle = Gesamtheit von abstrakten Methoden
interface C { void m (); }
Klassen können Schnittstellen implementieren:
class D implements C { void m () { .. } }
Eine Klasse implementiert mehrere Schnittstellen:
class D implements C1, C2 {
void m1 () { .. } ; void m2 () { .. }
}
Beachte: in Java keine Mehrfach-Vererbung (extends)
Bsp: Interfaces und Standard-Klassen
interface Collection {
interface Iterator
boolean add (Object o); boolean hasNext
Iterator iterator ();
Object next ();
}
}
class TreeSet
interface Set
implementes Set
extends Collection { }
String [] a = { "eins", "zwei", "drei", "vie
TreeSet t;
for (int k = 0; k < a.length; k++ )
{ t.add (a [k]); }
Iteraror it = t.iterator ();
while (it.hasNext())
{ System.out.print (it.next() + " "); }
Abstrakte Datentypen
trenne
• Aufgabenstellung
(Bsp: eine Menge von Objekten verwalten)
• von Lösung (Bsp: Verwaltung in geordnetem Baum)
Aufgabenstellung ⇒ Interface, Lösung ⇒ Klasse.
andere Sprechweise:
• Interface ⇒ abstrakter Datentyp,
• Klasse ⇒ konkreter Datentyp.
viele viele nützliche abstrakte und konkrete Typen:
http://java.sun.com/j2se/1.4.2/docs/api/
Applet-Programmierung
Applets
(Literatur: HKF ab S. 299)
Applet: in Webseite eingebettetes Programm
Ausführung im Web-Browser (zum Testen im
Applet-Viewer).
import java.applet.Applet;
import java.awt.*;
public class Counter extends Applet {
Label lab; Button inc;
public void init () {
lab = new Label ("0");
inc = new Button ("inc");
add (lab); add (dec);
}
}
Applets mit BlueJ programmieren und testen
• Project/New Class/applet (erzeugt Beispiel)
• Edit (Beispiel nur ansehen), Compile
• rechts-click auf Klassensymbol: Run Applet/Run Applet
in appletviewer
Ereignis-Behandlung in Applets
public class Counter {
int status = 0;
Label lab = new Label ("");
void update () {
lab.setText (Integer.toString (status));
}
...
public void init () {
add (lab);
...
}
}
Ereignis-Behandlung in Applets (II)
public class Counter { ...
Button inc = new Button ("inc");
class Inc_L implements ActionListener {
public void actionPerformed (ActionEvent a
status++; update ();
}
}
public void init () { ...
add (inc);
inc.addActionListener (new Inc_L ());
}
}
Aufgaben: füge Knöpfe für decrement und reset hinzu.
Applets in Webseiten einbetten
erzeuge Datei Counter.html:
<html>
<head> <title>Counter Applet</title> </head>
<body> <h1>Counter Applet</h1>
<applet code="Counter.class"
width=500 height=500
>
</applet>
</body> </html>
(BlueJ: Run Applet/Generate Web Page Only)
Datei Counter.class enthält Bytecode, entsteht durch
Kompilieren von Counter.java
(Quelltext ist zur Applet-Ausführung nicht nötig.)
Layout-Manager (19. 12.)
GUIs und Layout-Manager
Erklärungen und Beispiele: http://java.sun.com/
developer/onlineTraining/GUI/AWTLayoutMgr/
Ein GUI (graphical user interface) enthält mehrere
Komponenten (z. B. Labels, Buttons), die in einem
Container (z. B. Panel) angeordnet werden:
public class Thing extends Applet {
public void init () {
Button b = new Button ("bar"); add (b);
Button f = new Button ("foo"); add (f);
}
}
Explizite Positionierung (pfui)
setLayout (null);
Button b = new Button ("bar");
b.setBounds (200,300,50,30);
add (b);
Button f = new Button ("foo");
f.setBounds (100,200,100,40);
add (f);
Nachteile:
• keine Anpassung an variable Rahmengrößen
• keine Anpassung an variable Elementgrößen
• viel zu viele Zahlen
Implizite Positionierung durch Manager (gut)
fließende Anordnung (FlowLayout):
setLayout (new FlowLayout ()); // ist Defaul
for (int k = 0; k < 100; k++) {
add (new Button
( "B" + Integer.toString (k) ));
}
Beachte Wirkung von Window-Resize!
Gitter-Anordnung (GridLayout)
setLayout (new GridLayout (10,0));
ActionListener (Wiederholung)
Label top = new Label ("Top");
int status = 0;
void update () { top.setText
(Integer.toString (status));
}
class Step implements ActionListener {
int myself;
public Step (int k) { myself = k; }
public void actionPerformed (ActionEvent a
{ status += myself; update (); }
}
Button b = new Button ( .. );
b.addActionListener (new Step (11));
Manager (II)
Rahmen-Anordnung:
setLayout (new BorderLayout ());
add (new Button ("Top"), BorderLayout.NORTH)
add (new Button ("Foo"), BorderLayout.WEST);
add (new Button ("Bar"), BorderLayout.EAST);
add (new Button ("Bot"), BorderLayout.SOUTH)
add (new Button ("Mid"), BorderLayout.CENTER
Hier kann aber jeweils nur ein Element stehen — schade.
Container als Elemente von Containern
setLayout (new BorderLayout ());
add (new Button ("Top"), BorderLayout.NORTH)
add (new Button ("Foo"), BorderLayout.WEST);
Panel p = new Panel ();
p.setLayout (new GridLayout (10,0));
for (int k = 0; k < 97; k++) {
p.add (new Button( "B" + k ));
}
add (p, BorderLayout.CENTER);
(Bevorzugte) Abmessungen
Der Typ Dimension beschreibt Rechtecke.
(die meisten) Komponenten haben fließende
Abmessungen (d. h. können in verschiedenen Größen
dargestellt werden).
Jede Komponente hat Methoden
public Dimension getPreferredSize ();
public Dimension getMinimumSize ();
public Dimension getMaximumSize ();
Ein Layout-Manager kann diese Sizes seiner
Komponenten berücksichtigen,
. . . und muß selbst die Sizes seines Containers
ausrechnen.
Management von Abmessungen
• FlowLayout:
– stellt jede Komponente in preferredSize dar
– falls Container fest, dann Zeilenumbrüche
– preferred size des Containers: alles in einer Zeile
• GridLayout:
– Umbrüche nach festgelegter Zeilen- oder Spalten-Zahl
GridLayout(z,0) oder GridLayout(0,s)
– stellt alle Komponenten gleichgroß dar
– bestimmt dazu Maximum aller preferred sizes
– verkleinert/vergrößert alles so, daß es paßt
– preferredSize: nicht verkleinern
BorderLayout und preferred sizes
• Nord und Süd: Höhe ist preferred Höhe der Komponente,
• West und Ost: Breite ist preferred Breite,
• Mitte: was übrigbleibt
Aufgabe: finde Darstellung (Formel) für preferredSize des
Containers aus preferredSizes der fünf Komponenten!
Tip: oft hilft BorderLayout mit nur zwei oder drei
Komponenten.
Aufgabe: wann ist FlowLayout innerhalb anderer Container
sinnvoll? (selten!)
Layout (Zusammenfassung)
• Durch geeignete Schachtelung von Containern (Panels)
• und jeweils geeignete Manager
• lassen sich alle vernünftigen Layout-Aufgaben lösen,
• ohne auch nur eine einzige explizite Koordinate
anzugeben.
Für GUI-Entwurf: benutze Skizze (Zeichnung):
• gegenseitige Lage der Komponenten (Rechtecke)
• Verhalten bei Resize (Pfeile)
Gerechte Kuchen-Teilung
Gerechte Kuchen-Teilung
Jack Robertson and William Webb: Cake–Cutting
Algorithms,
http://www.akpeters.com/book.asp?bID=48
Beispiele: http://www.informatik.uni-leipzig.
de/˜joe/edu/ws01/xmas/
Programmier-Übungen (Januar)
Übung Applets
Quelltext:
http://www.imn.htwk-leipzig.de/˜waldmann/
ws03/informatik/programme/counter/
• kopieren, in BlueJ öffnen, kompilieren, ausprobieren.
• Fügen Sie einen Knopf dec (nach unten zählen) hinzu
• . . . reset (auf 0 setzen)
• Ändern sie Label auf TextField
• Fügen Sie Knopf set hinzu (soll Zähler auf aktuellen
Inhalt des Textfeldes setzen) Hinweis:
Button set = new Button ("set");
class Set_Listener implements ActionLi
public void actionPerformed (Actio
String s = ???
status = Integer.parseInt (s)
update ();
}
}
Übung Datenstrukturen
Quelltext:
http://www.imn.htwk-leipzig.de/˜waldmann/
ws03/informatik/programme/robots.zip
1. Kopieren, auspacken, in BlueJ öffnen (mit “open non
Bluej”), ausprobieren.
2. Wie werden Bewegungen implementiert? (State.java)
3. Wozu wird (Tree)Map verwendet? (Was ist Unterschied
zwischen Map und TreeMap? Benutze
Java-Dokumentation.)
4. ersetzen Sie TreeMap durch HashMap.
5. Erklären Sie eine Verwendung eines Iterators (Im
Zusammenhang mit Map und Set).
6. Implementieren Sie einen Test auf Erreichen des
Spielziels: neues Label, das anzeigt (“Ja”/”Nein”), ob alle
im Ziel sind. Hinweis:
... {
Set s = goals.keySet ();
Iterator i = s.iterator ();
while (...) {
String name = i.next ();
Point soll = (Point) goals.get (name);
Point ist = ...
if (! soll.equals (ist)) ...
}
}
7. Wie funktioniert der “Undo”-Button? (Hinweis: Stacks)
8. Implementieren Sie die Anzeige der Zugfolgen (am
besten gleich in der Form, die für das autotool paßt).
Datenstrukturen
Listen
Folge von Elementen [y0, y1, . . . , yn−1]
Methoden:
• Einfügen: void add (int i, Object o): aus Liste
[y0, y1, . . . , yi−1, yi, . . . , yn−1] wird Liste
[y0, y1, . . . , yi−1, o, yi, . . . , yn−1].
• Lesen: Object get (int i): Liste ist (und bleibt)
[y0, y1, . . . , yn−1], Resultat ist yi.
• Entfernen: Object remove (int i): aus Liste
[y0, y1, . . . , yi−1, yi, yi+1, . . . , yn−1] wird Liste
[y0, y1, . . . , yi−1, yi+1, . . . , yn−1], Resultat ist yi
• testen: size, isEmpty (Deklarationen?)
Beachte: bei add und remove ändern sich die Indizes der
Elemente auf bzw. nach i.
Wo ist der Konstruktor? Hinweis: List ist keine class,
sondern . . .
Bäume
Hierarchisch angeordnete Sammlung von Knoten
Jeder Knoten hat
• einen Schlüssel (Wert, Inhalt) (ein Objekt)
• eine Liste von Knoten (den Kindern)
Beispiele: Verwaltungen, HTML-Dokumente, biologische
Taxonomien, Menüs bei AV-Geräten,
Bezeichnungen:
• Wurzel: der Knoten, der kein Kind ist
• Blatt: Knoten mit leere Kinderliste
• innerer Knoten: kein Blatt.
Binäre Bäume
binärer Baum: jeder innere Knoten hat geanu zwei Kinder
(links, rechts)
vollständiger binärer Baum: alle Blätter gleich weit von
Wurzel entfernt.
(Pfadlänge = Anzahl der Verbindungen = Höhe des
Baumes.)
Wieviele Knoten hat ein vollständiger binärer Baum der
Höhe h?
Kellerspeicher (Stacks)
ein Keller is eine Folge von Elementen [y1, y2, . . . , yn]
Zugriffe (Lesen, Schreiben) sind links! Operationen:
• Stack () Konstruktor, erzeugt leeren Keller []
• einkellern: void push (Object o): aus Keller
[y1, y2, . . . , yn] wird Keller [o, y1, y2, . . . , yn]
• ansehen: Object peek (): Keller ist (und bleibt)
[y1, y2, . . . , yn], Resultat ist y1.
• auskellern: Object pop (): aus Keller [y1, y2, . . . , yn]
wird Keller [y2, . . . , yn], Resultat ist y1.
• testen: boolean empty (): is Keller leer, d. h. gleich
[]?
Implementiere peek() durch die anderen Methoden.
Wie kann man einen Keller kopieren (nur unter Benutzung
der angegebenen Methoden)?
Baum-Durchquerungen
Beispiel: Ausgabe von Operator-Ausdrücken:
void print (Knoten t) {
if t ist Blatt { print (t.key); }
else { print ( t.left );
print ( t.key );
print ( t.right );
}
}
Beispiel: Auswertung von Operator-Ausdrücken:
int wert (Knoten t) {
if t ist Blatt { return t.eintrag; }
else { int l = wert ( t.links );
int r = wert ( t.rechts );
return (l ‘t.key’ r);
}
}
Pre-, In-, Post-Order
• pre-order: Wurzel, linker Teilbaum, rechter Teilbaum
• in-order: linker Teilbaum, Wurzel, rechter Teilbaum
• post-order: linker Teilbaum, rechter Teilbaum, Wurzel
Ordne zu: Operator-Ausdruck drucken, Türme von Hanoi,
Operator-Ausdruck auswerten, Erlaß einer Regierung
bekanntgeben/umsetzen
(autotool) Rekonstruiere den binären Baum aus:
pre-order [5, 1, 7, 0, 9, 8, 2, 4, 3],
in-order [7, 1, 0, 5, 2, 8, 4, 9, 3]
Durchquerung ohne Rekursion
In welcher Reihenfolge werden hier die Knoten besucht?
int wert (Knoten t) {
Stack s = new Stack ();
push (t);
while (! s.empty ()) {
Knoten x = s.pop ();
print ( x.key );
if x ist kein Blatt {
s,push (x.right);
s.push (x.left);
} } }
Warteschlangen (Queues)
Speicher für Folge [y1, y2, . . . , yn], Schreiben nur links, und
Lesen nur rechts.
(in Java: als Teil von LinkedList)
• LinkedList () Konstruktor, erzeugt []
• schreiben void addFirst (Object o):
aus [y1, y2, . . . , yn] wird [o, y1, y2, . . . , yn]
• lesen: Object removeLast (): aus
[y1, y2, . . . , yn−1, yn] wird [y1, . . . , yn−1], Resultat ist yn.
• testen: boolean isEmpty (): ist Schlange leer, d. h.
gleich []?
Mit der Schlange durch den Baum
In welcher Reihenfolge werden hier die Knoten besucht?
int wert (Knoten t) {
LinkedList s = new LinkedList ();
addFirst (t);
while (! s.empty ()) {
Knoten x = s.removeLast ();
print ( x.eintrag );
if x ist kein Blatt {
s.addFirst (x.links);
s,addFirst (x.rechts);
} } }
heißt level-order
Rekonstruktions-Aufgabe?
Suchbäume
Ein Suchbaum ist ein binärer Baum, bei dem für jeden
inneren Knoten gilt:
jeder Schlüssel in t.links ist kleiner als t.key
und t.key ist kleiner als jeder Schlüssel in t.rechts
Suchbäume benutzt man, um Schlüssel schnell
wiederzufinden.
Suchen
gesuchten Schlüssel mit Schlüssel der Wurzel vergleichen,
nach links oder rechts absteigen und weitersuchen.
search (Knoten t, Key k) {
if ( t.key == k ) { return t; }
else {
if t ist kein Blatt {
if ( k < t.key ) {
return search (t.left, k);
} else {
return search (t.right, k);
} } } }
Einfügen
insert (Knoten t, Key k) {
if t ist kein Blatt {
if ( k < t.key ) {
insert (t.left, k);
} else {
insert (t.right, k);
}
} else {
if ( k < t.key ) {
t.left = new Blatt (k);
} else {
t.right = new Blatt (k);
}
} }
Löschen?
Blatt löschen ist einfach.
Wie löscht man einen inneren Knoten?
Balancierte Bäume: (2,3)-Bäume
(2,3)-Baum:
• alle Blätter sind gleich tief
und haben keine Schlüssel
• jeder innere Knoten ist
– ein 2-Knoten: 2 Kinder [l, r], 1 Schlüssel x
jeder Schlüssel in l < x < jeder Schlüssel in r
– ein 3-Knoten: 3 Kinder [l, m, r], 2 Schlüssel [x, y]
jeder Schlüssel in l < x < jeder Schlüssel in m < y <
jeder Schlüssel in r
Diese Eigeschaften (Invarianten) müssen bei allen
Operationen erhalten bleiben.
Eigenschaften von (2,3)-Bäumen
Ein (2,3)-Baum der Höhe n
hat wenigstens 1 + 2 + 22 + . . . + 2n = 2n+1 − 1 Knoten
und höchstens 1 + 3 + 32 + . . . + 3n = (3n+1 − 1)/2 Knoten.
Aufgabe: wieviele Knoten hat ein (2,3)-Baum der Höhe 10
wenigstens? höchstens?
Aufgabe: welche Höhe hat ein (2,3)-Baum mit 106 Knoten
wenigsten? höchstens?
Einfügen in (2,3)-Bäume
(Suchen funktioniert ähnlich wie bei binären Suchbäumen.)
• suchen den Knoten (direkt über Blättern), der neuen
Schlüssel aufnehmen sollte.
• aus 2-Knoten wird 3-Knoten (OK),
• aus 3-Knoten wird 4-Knoten (verboten).
• Lösung:
– diesen 4-Knoten in zwei 2-Knoten (und einen
Schlüssel) zerlegen,
– diesen Schlüssel in Vorgänger einfügen
(a, b)-Bäume
Das funktioniert statt (2, 3) genauso für Zahlen (a, b) mit
a ≤ (b + 1)/2. (Warum diese Einschränkung?)
Für große Datenbanken benutzt man z. B. a = 10, b = 100.
¡¡¡¡¡¡¡ top.tex =======
¿¿¿¿¿¿¿ 1.4
Software-Technik
Ergonomische Software
Ziel: angenehm für Benutzer und Programmierer
erfordert fachmännisches Vorgehen auf verschiedenen
Ebenen:
• Gesamt-Projekt
• Implementierung im Großen
• Programmieren im Kleinen
Software-Projekt-Manangement
Arbeitsschritte (klassische: nacheinander)
• Analyse
• Spezifikation
• Entwurf
• Implementierung
• Test
• Betrieb
Software-Projekt-Manangement (II)
beachte auch (in jedem Schritt):
• Qualitätssicherung
• Kontakt zum Kunden
modern“: extreme programming, rapid prototyping,
”
refactoring
Richtlinien zur Algorithmenkonstruktion
(vgl. Horn/Kerner/Forbrig S. 213 f.)
• Hierarchische Struktur:
–
–
–
–
–
Algorithmus ist ein Baum,
jeder Teilbaum löst ein Teilproblem,
in jedem inneren Knoten steht die Spezifikation,
seine Kinder sind die Teilschritte der Lösung.
Die Blätter sind elementare Operationen.
• Top-Down-Entwicklung, schrittweise Verfeinerung
Richtlinien (II)
• Blockstruktur:
– jeder Teilbereich hat genau einen Ein- und einen
Ausgang
– und erfüllt einen Vertrag (wenn Vorbedingung zutrifft,
dann ist nach Ausführung die Nachbedingung wahr)
• Lokalität der Daten: Programmbereiche, die bestimmte
Daten benutzen, sollten
– wenig überlappen
– den Kontrollbereichen entsprechen
Modulare Programmierung
Modul
• funkionell abgeschlossener Teil eines Softwareprojektes,
• der separat entwickelt wird.
modulares Programmieren erlaubt
• Anwenden der Richtlinien (top-down usw.)
• getrenntes, zeitgleiches Entwickeln
• Einsparungen durch Nachnutzen von eigenen und
fremden Modulen
Modul-Schnittstellen
Modul besteht aus
• Schnittstelle und
• Implementierung
Die Nutzer eines Modules (= aufrufende Programme)
kennen nur die Schnittstelle. (Lokalität der Daten,
Datenabstraktion)
Damit kann Implementierung leicht ausgetauscht werden
(→ flexibel, portabel)
Re-Factoring
auch während und nach der Entwicklung immer weiter
modularisieren:
• Können weitere Module genutzt werden?
• Kann Funkionalität in neue Module ausgelagert werden?
nach rapid prototyping mit der Axt reingehen“, vornehme
”
Bezeichnung: re-factoring.
ist geboten bei
• überlangen Modul-Quelltexten (d. h. > 1 Bildschirmseite
!)
• Code-Verdopplungen (verschiedene Programmteile mit
ähnlicher Funktion)
Module in Java?
Hilfsmittel für modulares Programmieren:
• Klassen,
• Interfaces,
• Packages.
beachte: Objekt-Orientierung 6= Modularisierung,
in Java wurde Objekt/Klassen-Konzept erweitert (Wdhlg:
wodurch?), und es muß nun auch Modularisierung
ausdrücken.
Klassen als Module
Klasse beschreibt Objekte (Attribute und Methoden). Dient
damit zum Strukturieren und Zusammenfassen von
Algorithmen.
Wie kann Implementierung versteckt werden?
Attribute und Methoden, die als private deklariert sind,
können nur innerhalb der Klasse benutzt werden.
Damit bilden die nicht-privaten Attribute und Methoden die
Schnittstelle der Klasse.
Regel: grundsätzlich alle Attribute privat deklarieren,
damit jedes Lesen und Schreiben von außen“ bemerkt
”
wird und korrekt behandelt werden kann.
Interfaces
Ein Interface beschreibt Gemeinsamkeiten von
Modul-Schnittstellen.
andere Sprechweise:
• Interface = abstrakter Datentyp = Spezifikation
• Klasse = konkreter Datentyp = Implementierung
Programmierer entscheidet zunächst, welcher abstrakter
Datentyp benötigt wird,
und wählt dann einen dazu passenden konkreten Datentyp
aus.
Beispiel: ADT Menge, konkret: Bitfolge, Liste, Suchbaum.
Packages
Ein Package ist eine Sammlung von Klassen (und
Interfaces).
Beispiel: java.applet ist ein Package.
Man bezeichnet Methode m der Klasse C aus Package P
durch P.C.m
Man kann P. weglassen, wenn vorher import P.C stand.
import P.* macht alle Klassen aus P sichtbar.
Die Schnittstelle eines Packages enthält:
alle als public deklarierten Klassen, Attribute und
Methoden.
Packages in Archiven
Interesse an Modularisierung und Daten-Abstraktion nicht
nur wegen der schönen Entwurfsprinzipien.
Programmtext der Implementierung einer Schnittstelle soll
versteckt werden oder ganz entfallen, weil er
• zu groß ist
• noch verarbeitet (kompiliert) werden muß
• geheim bleiben soll
Zur korrekten Benutzung eines Modules ist es ausreichend
und effizient, wenn die Implementierung kompiliert vorliegt.
Kompilierte Klassen eines Packages werden in
Package-Archive (P.jar) komprimiert gespeichert.
Freie“ Software
”
Der naive “ unternehmerische Ansatz ist, ein
”
Softwareprojekt zu entwickeln und dann das kompilierte
Produkt zu verkaufen oder zu vermieten.
Andererseits sind Programme Texte, also Gedanken, und
diese sind bekanntlich frei.
Die Idee der Freien Software ist es, Software (Quelltexte)
grundsätzlich zu veröffentlichen, weil so der größte Nutzen
für die Allgemeinheit entsteht.
Freie“ Software
”
Warum sollte das ein Entwickler/eine Firma tun? Wovon
soll er dann leben? Vom Verkauf von Dienstleistungen
(Installation, Wartung, Schulung).
Damit leben die späteren Dienstleister auf Kosten der
früheren Programmierer? Nein, sie schreiben selbst freie
Software.
Freie“ Software (II)
”
Frei sein heißt für Software:
• Programmierer bleibt Autor und Urheber
• Quelltext ist frei verfügbar, jeder darf ihn nutzen (d. h.
lesen, kompilieren, ausführen)
• und auch verändern und erweitern
• aber alle Änderungen müssen frei bleiben.
Siehe auch Free Software Foundation
http://fsf.org/, GAOS e.V. Leipzig
http://goas.org/.
Freie“ Software (II)
”
Bekannte und berühmte freie Software-Projekte sind
• Emacs (Editor)
• GCC (Compiler), ab 197?
• GNU (= GNU’s Not Unix): Dienst- und
Anwendungsprogramme für ein UNIX-ähnliches
Betriebssystem, ab 198?
• Linux, ein Betriebssystem-Kern, ab ca. 1990
und vieles andere mehr: (TEX), KDE, Mozilla, gnugo, . . .
Free Software Directory:
http://www.gnu.org/directory/,
Freie Software als Wirtschaftsfaktor
für den Anwender ist es natürlich billiger . . .
allerdings entstehen Dienstleistungskosten
freie Software-Entwicklung ist flexibler (anpassungsfähiger,
schneller)
nutzt z. B. schnelle Hardware viel besser aus als veraltete
Systeme
auch große Firmen wollen da mitspielen (und sich street
credibility kaufen)
IBM unterstützt Linux, Sun gibt Java-Technologie frei
Freie Spezifikationen
Zur Informatik-Anwendung gehören nicht nur Software,
sondern auch Hardware und Protokolle.
Wenn deren Spezifikationen aber nicht frei sind, kann
dafür niemand Software (Treiber) schreiben,
und so bleibt der Hersteller nach einer Weile auf seiner
Hardware sitzen, weil sie nur (wenn überhaupt) mit
anderen eigenen Produkten kompatibel ist.
Davon hängt also viel Geld ab! Die Erkenntnis, daß freie
Spezifikationen (Standards) der Gesamtwirtschaft mehr
nutzen (als sie Einzelnen schaden) hat sich im
wesentlichen durchgesetzt.
Bsp: Internet, ISO 9660 (CD-ROM, DVD), IEEE 1394
Wissenschaft, Freiheit, Sicherheit
Jede Wissenschaft lebt vom Publizieren von Ideen (und
nicht vom Geheimhalten).
Nur dadurch können diese geprüft, implementiert und
entwickelt werden.
Beispiel: Kryptographie, Systemsicherheit.
Sollte man kritische “ Algorithmen lieber doch
”
geheimhalten?
Ganz falsch!
Sicher sind nur Verfahren, deren Sicherheit
wissenschaftlich bewiesen wurde. Gerade dazu müssen
sie veröffentlich werden.
Zahlentheorie, Komplexitätstheorie usw.
Ales frei = alles gut?
wie Prof. J. Winkler http://psc.informatik.
uni-jena.de/personen/perso.htm, der bei Siemens
die (natürlich unfreien) Compiler für CHILL und Ada gebaut
hat, an dieser Stelle zu sagen pflegte:
There is no such thing as a free lunch.
RTFC
Der Bildungs- und Unterhaltungswert freier Quelltexte ist
jedenfalls unbestritten.
Von UCB (Univ. Calif. Berkeley) wird berichtet, daß dort (in
den goldenen 70er Jahren) überhaupt kein Programm
installiert werden durfte, ohne gleichzeitig den kompletten
Quelltext im gleichen Directory abzulegen.
In diesem Sinne . . . RTFC = read the fXXXing code!
Zusammenfassung
• Informatik und Algorithmen
– Geschichte der Informatik
– Komplexität von Algorithmen
– Sortier-Algorithmen (bubble, merge, quick)
• Grundlagen der Programmierung
–
–
–
–
Daten (einfache, zusammengesetzte)
Anweisungen/Kontrollstrukturen
Ausdrücke (Ausdrucksbäume)
Typen
Zusammenfassung (II)
• Objektorientiertes Programmieren
–
–
–
–
Objekte, Methoden, Attribute, Klassen, Interfaces
Aggregation, Vererbung
Überladen, Überschreiben
GUI: Layout-Management, Ereignis-Behandlung
• Datenstrukturen
– Listen, Stacks, Queues
– Bäume, Durchquerungen, Balance
• Softwaretechnik
– Entwurfsregeln
– Module, Schnittstellen
– abstrakte und konkrete Datentypen
Autotool – Highscore – Auswertung
67 935198 Enrico Unger
57 35202 Markus Unger
45 34985 Tanja Czerwinski
27 . . .
Preise (teilweise) gesponsort von
http://www.capitospiele.de/
Test-Fragen
Test-Fragen
Was ist ein Algorithmus?
zur Computer-Architektur nach von Neumann: was ist ein
Programmzustand? welche zwei elementaren
Programmbausteine gibt es?
wo steht das Programm? was folgt daraus?
Welche Möglichkeiten gibt es beim strukturierten
Programmieren, die Abarbeitungsreihenfolge zu
beeinflussen?
Welche (zwei!) Beziehungen müssen zwischen Eingabe
und Ausgabe eines Sortier-Algorithmus gelten?
Wie definiert man die Komplexität eines Algorithmus?
Nennen Sie die Komplexität von zwei Sortierverfahren.
Auf welchem Algorithmen-Entwurfs-Prinzip beruht a)
Bubblesort, b) Mergesort?
Wie definiert man die Komplexität eines Problems?
Nennen Sie ein algorithmisch unlösbares Problem.
Welche Gemeinsamkeiten, welche Unterschiede gibt es
zwischen Prozeduren und Funktionen?
Was ist ein Datentyp? Nennen Sie einige einfache und
einige zusammengesetzte Typen.
Wann und wie werden Typ-Informationen ausgenutzt?
Was ist ein Objekt? Wozu benutzt man Klassen?
Wie muß die Methode foo der Klasse C deklariert sein,
damit folgender Aufruf korrekt ist:
C x = new C ();
int y = 4 + x.foo ("bar", 6);
Zeichnen Sie den Syntaxbaum für den Ausdruck
i < a [ a.length - i ]
und beschriften Sie jeden Knoten mit seinem Typ. Wie
müssen i und a deklariert sein?
Warum werden in Java Objekte nicht als Wert, sondern
durch Verweis an Unterprogramme übergeben? (Zwei
Gründe.)
Wie ist ein Konstruktor für eine Klasse C zu deklarieren,
der ein Argument vom Typ int hat?
Erläutern Sie die Bezeichnungen Aggregation und
Vererbung für Beziehungen zwischen Klassen.
Welche Gemeinsamkeiten und Unterscheide gibt es
zwischen Überladen und Überschreiben von Methoden?
Folgende Deklarationen sind gegeben:
class C {
int f (int x) { ... }
int f (int x, int y) { ... }
int g (int z) { ... }
int h (int x, C y) { ... }
}
class D extends C {
int f (int x) { ... }
}
class E {
int f (int x) { ... }
}
Kennzeichnen Sie Überladungen, Überschreibungen.
Die folgenden Objekte sind deklariert
C c; D d; E e;
Sind die folgenden Methoden-Aufrufe korrekt? Falls ja,
welches Unterprogramm wird jeweils tatsächlich
aufgerufen? (Wir nehmen an, daß die Variablen initialisiert
wurden.)
c.f (); c.f ("foo");
d.f (4); d.g (5);
d.f (4, 6); e.f (4, 6);
c.h (8, d);
Untersuchen Sie, ob alle Bedingungen bei der Benutzung
der static-Annotation erfüllt sind:
class C {
static int i;
int j;
static int f (int x) {
return i + 2 * j;
}
int g (int x) { ... }
static void check () {
System.out.println (f (3) * g (4));
}
}
Welche Aufgabe hat ein ActionListener, wie wird
dieses Interface in einem Applet benutzt?
Warum sollte man zum Layout der Komponenten eines
GUI einen Manager benutzen?
Was ist ein Interface?
Welche Beziehungen sind zwischen einem Interface und
anderen Programmteilen möglich?
Warum geht das nicht:
interface Foo { ... }
...
Foo x = new Foo ();
Sowohl ein Array als auch eine Liste speichert eine Folge
von Elementen.
Welche Listen-Operation ist für Arrays nicht ausführbar?
Sowohl ein Baum als auch eine Liste speichern eine
Menge von Elementen (Schlüsseln).
Wieso ist ein Baum günstiger, wenn man oft über die
Schlüssel auf die Elemente zugreifen muß?
Beweis oder Gegenbeispiel: wenn man die
Pre-Order-Reihenfolge eines binären Baumes spiegelt,
dann erhält man die Post-Order-Reihenfolge.
Wie kann man aus einer vorgegebenen Liste von
Schlüsseln einen balancierten Suchbaum herstellen?
(Hinweis: nicht durch wiederholtes Einfügen)
Herunterladen