23.10.2014 Aufrufe

Einführung in die Informatik I Kapitel 6: Reihungen, Sortieren und ...

Einführung in die Informatik I Kapitel 6: Reihungen, Sortieren und ...

Einführung in die Informatik I Kapitel 6: Reihungen, Sortieren und ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I<br />

Prof. Bernd Brügge, Ph.D.<br />

Technis/che Universität München<br />

W<strong>in</strong>tersemester 2003/2004<br />

<strong>Kapitel</strong> 6:<br />

<strong>Reihungen</strong>, <strong>Sortieren</strong> <strong>und</strong> Suchen<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 1<br />

2


Überblick über <strong>die</strong>sen Vorlesungsblock<br />

v Themen:<br />

– <strong>Reihungen</strong> (arrays): e<strong>in</strong>- <strong>und</strong> mehrdimensionale <strong>Reihungen</strong><br />

– Werte <strong>und</strong> Referenzsemantik<br />

– Parameterübergaben (Wert <strong>und</strong> Referenzübergaben)<br />

– <strong>Sortieren</strong> von <strong>Reihungen</strong><br />

– Suchen <strong>in</strong> <strong>Reihungen</strong><br />

v Ziele:<br />

– Sie s<strong>in</strong>d <strong>in</strong> der Lage, Probleme zu lösen, <strong>die</strong> e<strong>in</strong>e Menge von Daten<br />

erfordern.<br />

– Sie verstehen den Unterschied zwischen e<strong>in</strong>fachen Variablen <strong>und</strong><br />

Referenzvariablen.<br />

– Sie können aktiv mit <strong>Reihungen</strong> umgehen, <strong>in</strong>sbesondere <strong>in</strong> der<br />

Implementation von Algorithmen.<br />

– Sie s<strong>in</strong>d <strong>in</strong> der Lage, Probleme zu lösen, <strong>die</strong> Daten mit mehreren<br />

Dimensionen erfordern.<br />

– Sie beherrschen erste Sortierverfahren: bubble sort, selection sort,<br />

<strong>in</strong>sertion sort<br />

– Sie können <strong>in</strong> <strong>Reihungen</strong> effizient suchen.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 2


<strong>Reihungen</strong><br />

v E<strong>in</strong>e Reihung (array) ist e<strong>in</strong>e Menge von Variablen, <strong>die</strong> Werte<br />

desselben Typs speichern.<br />

v E<strong>in</strong>e e<strong>in</strong>zelne Variable wird nicht durch ihren Namen benannt,<br />

sondern durch ihre Position <strong>in</strong>nerhalb der Reihung.<br />

v Beispiel: Ausgabe der Studentennamen, <strong>die</strong> <strong>in</strong> e<strong>in</strong>em Verzeichnis<br />

gespeichert s<strong>in</strong>d:<br />

Ohne Reihung<br />

System.out.pr<strong>in</strong>tln(student1);<br />

System.out.pr<strong>in</strong>tln(student2);<br />

System.out.pr<strong>in</strong>tln(student3);<br />

System.out.pr<strong>in</strong>tln(student4);<br />

System.out.pr<strong>in</strong>tln(student5);<br />

System.out.pr<strong>in</strong>tln(student6);<br />

System.out.pr<strong>in</strong>tln(student7);<br />

Mit Reihung<br />

for (<strong>in</strong>t k = 1; k


1-dimensionale <strong>Reihungen</strong><br />

v E<strong>in</strong>e Variable <strong>in</strong> e<strong>in</strong>er Reihung wird durch ihre Position <strong>in</strong>nerhalb der<br />

Reihung bezeichnet, nicht durch e<strong>in</strong>en eigenen Bezeichner.<br />

– In e<strong>in</strong>er Reihung von n Variablen mit dem Bezeichner arr werden <strong>die</strong><br />

Variablen so benannt: arr[0],arr[1],arr[2],…,arr[n-1].<br />

v Die folgende Reihung umfasst 8 Variablen vom Typ <strong>in</strong>t.<br />

Die Indizierung<br />

von <strong>Reihungen</strong><br />

beg<strong>in</strong>nt <strong>in</strong> Java<br />

immer bei 0<br />

arr:<br />

Index<br />

0 1 2 3 4 5 6 7<br />

-2 8 -1 16 16 45 21 -3<br />

Reihungsname<br />

Syntax e<strong>in</strong>er Reihungsdeklaration:<br />

typbezeichner[] arrayname;<br />

wobei<br />

- arrayname der Name der Reihung ist, <strong>und</strong><br />

- typbezeichner der Typ der Reihungsvariablen.<br />

Elementwert<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 4


Term<strong>in</strong>ologie<br />

v E<strong>in</strong>e leere Reihung enthält ke<strong>in</strong>e Variablen.<br />

v Die Variablen <strong>in</strong> e<strong>in</strong>er Reihung heißen auch Reihungselemente oder<br />

kurz Elemente.<br />

v Jedes Element <strong>in</strong> e<strong>in</strong>er Reihung hat denselben Typ, auch Elementtyp<br />

genannt.<br />

v Die Länge e<strong>in</strong>er Reihung ist <strong>die</strong> Anzahl ihrer Elemente.<br />

v Jedes Reihungsobjekt hat e<strong>in</strong> Attribut length, das <strong>die</strong> Länge der<br />

Reihung angibt.<br />

– arr.length ist im Beispiel der vorigen Folie gleich 8.<br />

v Reihungselemente können beliebige Typen se<strong>in</strong>, e<strong>in</strong>schließlich<br />

<strong>Reihungen</strong> <strong>und</strong> Klassen.<br />

– In Java: E<strong>in</strong>e 2-dimensionale Reihung ist e<strong>in</strong>e Reihung von<br />

<strong>Reihungen</strong> von Elementen e<strong>in</strong>es Typs<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 5


Zugriff auf Elemente <strong>in</strong> e<strong>in</strong>er Reihung<br />

arr:<br />

Gegeben seien <strong>die</strong> Deklarationen: <strong>in</strong>t j = 5, k = 2;<br />

Gültige Elementzugriffe s<strong>in</strong>d:<br />

arr[1] // Bezeichnet den Wert 8<br />

arr[0] // Bezeichnet den Wert -2<br />

arr[j + k] // Ergibt arr[5+2], d.h. arr[7], also -3<br />

arr[j % k] // Ergibt arr[5%2], d.h. arr[1], also 8<br />

Ungültige Elementzugriffe:<br />

-2 8 -1 16 16 45 21 -3<br />

arr[5.0] // 5.0 ist e<strong>in</strong>e Gleitkommazahl (double),<br />

// kann also nicht Index se<strong>in</strong>.<br />

arr['5'] // '5' ist vom Typ char, nicht von Typ <strong>in</strong>t<br />

arr[-1] // Negative Indizes s<strong>in</strong>d nicht möglich.<br />

arr[8] // Das letzte Element von arr hat Index 7<br />

arr[j*k] // j*k ist gleich 10, als außerhalb des<br />

// Indexbereiches<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 6


Deklaration <strong>und</strong> Instantiierung e<strong>in</strong>er Reihung<br />

v Um e<strong>in</strong>e 1-dimensionale Reihung zu deklarieren, müssen wir den<br />

Namen der Reihung <strong>und</strong> auch den Typ der Elemente angeben.<br />

v Um e<strong>in</strong>e Reihung zu <strong>in</strong>stantiieren, müssen wir den new-Operator<br />

benutzen, der den Elementtyp <strong>und</strong> <strong>die</strong> Länge der Reihung benötigt.<br />

<strong>in</strong>t[] arr;<br />

// Deklaration e<strong>in</strong>er Reihung<br />

arr = new <strong>in</strong>t[15]; // Instantiierung e<strong>in</strong>er Reihung von 15<br />

// Elementen<br />

Wir können beide Aktivitäten <strong>in</strong> e<strong>in</strong>em Schritt vere<strong>in</strong>en:<br />

<strong>in</strong>t[] arr = new <strong>in</strong>t[15];<br />

Der Name der<br />

Reihung ist arr.<br />

Die Reihung enthält 15<br />

Variablen vom Typ <strong>in</strong>t.<br />

Die 15 Variablen: arr[0], arr[1], .., arr[14]<br />

Indexwerte von 0 bis arr.length-1 zulässig.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 7


Was genau passiert bei Deklaration <strong>und</strong><br />

Instantiierung e<strong>in</strong>er Reihung?<br />

Deklaration e<strong>in</strong>er Reihungsvariable:<br />

<strong>in</strong>t[] arr;<br />

Nach der Deklaration ist der Wert<br />

der Reihungsvariable null.<br />

arr: null<br />

Die new-Operation <strong>in</strong>stantiiert e<strong>in</strong>e<br />

Reihung, deren Inhalte mit dem<br />

Default-Wert 0 vorbesetzt s<strong>in</strong>d.<br />

new <strong>in</strong>t[8]<br />

0 0 0 0 0 0 0 0<br />

Die Zuweisung ersetzt den null-Wert durch e<strong>in</strong>en Verweis auf das<br />

Reihungsobjekt.<br />

arr = new <strong>in</strong>t[8];<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 8


Initialisierung von <strong>Reihungen</strong><br />

v Bei der Deklaration werden <strong>Reihungen</strong> <strong>und</strong> Reihungselemente <strong>in</strong><br />

Java mit Vore<strong>in</strong>stellungswerten (default values) <strong>in</strong>itialisiert:<br />

– Reihungsvariablen werden auf den Wert null <strong>in</strong>itialisiert.<br />

– Reihungselemente mit Typen <strong>in</strong>t, boolean, … werden auf 0,<br />

false, ... <strong>in</strong>itialisiert.<br />

v Reihungselemente kann man bereits bei der Deklaration der<br />

Reihung mit <strong>in</strong>itialen Werten versehen:<br />

<strong>in</strong>t[] arr = {-2,8,-1,-3,16,20,25,16,16,8,18,19,45,21,-2};<br />

Regel: Wenn e<strong>in</strong>e Reihung bereits bei der Deklaration <strong>in</strong>itialisiert wird,<br />

dann brauchen wir den new-Operator nicht mehr, um <strong>die</strong> Reihung zu<br />

kreieren (<strong>die</strong> Instantiierung der Reihung hat bereits bei der Deklaration<br />

stattgef<strong>und</strong>en!).<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 9


Zuweisung <strong>und</strong> Benutzung von Reihungswerten<br />

Indizierte Reihungsariablen benutzen wir genauso wie andere<br />

Variablen:<br />

arr[0] = 5;<br />

arr[5] = 10;<br />

arr[2] = 3;<br />

E<strong>in</strong> Programmstück, das <strong>die</strong> ersten 15 Quadratzahlen (1, 4, 9, 16, …)<br />

der Reihung arr zuweist:<br />

<strong>in</strong>t[] array = new <strong>in</strong>t[15];<br />

for (<strong>in</strong>t k = 0; k < arr.length; k++)<br />

arr[k] = (k+1) * (k+1);<br />

E<strong>in</strong>e Schleife zum Drucken der Werte von arr:<br />

for (<strong>in</strong>t k = 0; k < arr.length; k++)<br />

System.out.pr<strong>in</strong>tln(arr[k]);<br />

Wichtig: length<br />

ist e<strong>in</strong> Attribut von<br />

arr, ke<strong>in</strong>e Methode.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 10


Beispiel: Ausdruck von Werten<br />

Drucke e<strong>in</strong>e Reihung für Elemente vom Typ <strong>in</strong>t <strong>und</strong> e<strong>in</strong>e Reihung<br />

für Elemente vom Typ double:<br />

public class Pr<strong>in</strong>tArrays {<br />

public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />

<strong>in</strong>t <strong>in</strong>tArr[] = new <strong>in</strong>t[10]; // Kreiere <strong>die</strong> Reihung <strong>in</strong>tArr<br />

double realArr[] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8,<br />

9.9, 10.10 }; // <strong>und</strong> e<strong>in</strong>e vor<strong>in</strong>itialisierte<br />

// Reihung von Gleitkommawerten<br />

System.out.pr<strong>in</strong>tln("Int \t Double");<br />

Int Double<br />

for (<strong>in</strong>t k = 0; k < <strong>in</strong>tArr.length; k++)<br />

0 1.1<br />

System.out.pr<strong>in</strong>tln( <strong>in</strong>tArr[k] + " \t " + realArr[k]);<br />

0 2.2<br />

0 3.3<br />

0 4.4<br />

0 5.5<br />

0 6.6<br />

0 7.7<br />

0 8.8<br />

0 9.9<br />

0 10.1<br />

} // ma<strong>in</strong>()<br />

} // Pr<strong>in</strong>tArrays<br />

Die Reihung <strong>in</strong>tArr ist nicht <strong>in</strong>itialisiert,<br />

alle Elemente haben also<br />

Vore<strong>in</strong>stellungswerte 0.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 11


Beispiel: Speichere <strong>und</strong> drucke 100 Quadratzahlen<br />

public class Squares {<br />

public static void ma<strong>in</strong>(Str<strong>in</strong>g args[]) {<br />

f<strong>in</strong>al <strong>in</strong>t ARRSIZE = 100;<br />

// Größe der Reihung ist e<strong>in</strong>e Konstante<br />

<strong>in</strong>t <strong>in</strong>tArr[] = new <strong>in</strong>t[ARRSIZE]; // Deklariere <strong>und</strong> kreiiere <strong>die</strong><br />

// Reihung<br />

for (<strong>in</strong>t k = 0; k < <strong>in</strong>tArr.length; k++) // Initialisierung der Reihung<br />

<strong>in</strong>tArr[k] = (k+1) * (k+1);<br />

System.out.pr<strong>in</strong>t("Die ersten 100 Quadratzahlen:"); // Kopf der Tabelle<br />

for (<strong>in</strong>t k = 0; k < <strong>in</strong>tArr.length; k++) {<br />

// Drucke <strong>die</strong> Reihung<br />

if (k % 10 == 0)<br />

// 10 Elemente pro Reihe<br />

System.out.pr<strong>in</strong>tln(" ");<br />

System.out.pr<strong>in</strong>t( <strong>in</strong>tArr[k] + " ");<br />

} // for<br />

} // ma<strong>in</strong>()<br />

} // Squares<br />

Die ersten 100 Quadratzahlen:<br />

1 4 9 16 25 36 49 64 81 100<br />

121 144 169 196 225 256 289 324 361 400<br />

441 484 529 576 625 676 729 784 841 900<br />

961 1024 1089 1156 1225 1296 1369 1444 1521 1600<br />

1681 1764 1849 1936 2025 2116 2209 2304 2401 2500<br />

2601 2704 2809 2916 3025 3136 3249 3364 3481 3600<br />

3721 3844 3969 4096 4225 4356 4489 4624 4761 4900<br />

5041 5184 5329 5476 5625 5776 5929 6084 6241 6400<br />

6561 6724 6889 7056 7225 7396 7569 7744 7921 8100<br />

8281 8464 8649 8836 9025 9216 9409 9604 9801 10000<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 12


Zuweisung von <strong>Reihungen</strong><br />

Wir kennen schon <strong>die</strong> Situation nach folgender Deklaration <strong>und</strong><br />

Instantiierung: <strong>in</strong>t[] a = new <strong>in</strong>t[8];<br />

a:<br />

0 0 0 0 0 0 0 0<br />

Was passiert nun, wenn wir e<strong>in</strong>e zweite Reihungsvariable<br />

deklarieren <strong>und</strong> ihr den Wert von a zuweisen? <strong>in</strong>t[] b = a;<br />

Das Reihungsobjekt wird <strong>in</strong> Java nicht etwa kopiert,<br />

a:<br />

b:<br />

0 0 0 0 0 0 0 0<br />

0 0 0 0 0 0 0 0<br />

sondern es entsteht e<strong>in</strong> zweiter Verweis auf dasselbe Objekt!<br />

a:<br />

0 0 0 0 0 0 0 0<br />

b: Änderungen an b wirken sich ab sofort auch auf a aus!<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 13


<strong>Reihungen</strong> s<strong>in</strong>d Objekte<br />

v In Java werden <strong>Reihungen</strong> (arrays) wie Objekte behandelt:<br />

– Sie werden mit dem new Operator <strong>in</strong>stantiiert.<br />

– Sie haben Attribute (<strong>in</strong>stance variables), z.B. length.<br />

– Allerd<strong>in</strong>gs: Es gibt ke<strong>in</strong>e "Klasse" Array <strong>in</strong> Java.<br />

v In Java gibt es 2 Arten von Variablen:<br />

– E<strong>in</strong>fache Variable:<br />

u Variable vom Typ <strong>in</strong>t, float, double, boolean<br />

– Referenzvariable:<br />

u Variable vom Typ array oder e<strong>in</strong>er benutzerdef<strong>in</strong>ierten Klasse<br />

(z.B. Student) oder e<strong>in</strong>er vordef<strong>in</strong>ierten Klasse (z.B. Str<strong>in</strong>g).<br />

v Die Semantik bei Zuweisungen an <strong>die</strong>se Variablen ist verschieden:<br />

– Wertesemantik für e<strong>in</strong>fache Variable<br />

– Referenzsemantik für Referenzvariablen<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 14


Wertesemantik von Variablen<br />

v E<strong>in</strong>e Variable ist def<strong>in</strong>iert als e<strong>in</strong> Tupel (Name, Wert).<br />

– Der Name ist genauer gesagt e<strong>in</strong>e Zugriffsfunktion,<br />

mit der wir den "Platz" der Variablen berechnen, <strong>und</strong><br />

dann den Wert lesen oder ihn schreiben.<br />

Name<br />

a :<br />

Wert<br />

5<br />

<strong>in</strong>t a, b; a = 5; b = 8;<br />

Zugriffsfunktion<br />

v Wir nennen <strong>die</strong>se Auffassung <strong>die</strong> Wertsemantik von<br />

Variablen:<br />

– Wir bezeichnen Variablen mit Wertsemantik auch als<br />

Wertobjekte <strong>und</strong> ihre Typen als Werttypen.<br />

– Beispiele von Wertobjekten: Variable vom Typ boolean, <strong>in</strong>t,<br />

char, float, double.<br />

v Bei Wertobjekten kann man direkt auf <strong>die</strong> Werte über den<br />

Namen zugreifen.<br />

b :<br />

8<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 15


Referenzsemantik von Variablen<br />

Verweisvariable<br />

v E<strong>in</strong>e Variable mit Referenzsemantik ist immer noch e<strong>in</strong><br />

Tupel (Name, Wert). Allerd<strong>in</strong>gs<br />

– Der Wert ist jetzt e<strong>in</strong>e Referenz (Verweis,<br />

"Addresse", "Po<strong>in</strong>ter") auf e<strong>in</strong>e Variable <strong>die</strong><br />

als Wert e<strong>in</strong> Objekt hat (z.B. <strong>die</strong> Instanz<br />

e<strong>in</strong>er Klasse oder e<strong>in</strong>e Reihung).<br />

u Diese Variable wird auch Verweisvariable<br />

genannt.<br />

Name<br />

stud1<br />

:<br />

Student<br />

x45454423<br />

Student stud1, stud2;<br />

stud1 = new Student()<br />

Zugriffsfunktionen<br />

stu<strong>die</strong>rt<br />

denkt<br />

schlaeft<br />

stu<strong>die</strong>re()<br />

denke()<br />

schlafe()<br />

true<br />

false<br />

false<br />

stud2<br />

:<br />

null<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 16


Variable mit Referenzsemantik:<br />

Das Ganze noch e<strong>in</strong>mal<br />

Verweisvariable<br />

Name<br />

student stud1, stud2;<br />

stud1 = new Student();<br />

Zugriffsfunktionen<br />

stud1<br />

:<br />

x45454423 null<br />

Der Wert der Verweisvariablen<br />

ist e<strong>in</strong>e Referenz<br />

auf e<strong>in</strong> Objekt vom Typ<br />

Student<br />

Student<br />

stu<strong>die</strong>rt<br />

denkt<br />

schlaeft<br />

true<br />

false<br />

false<br />

Verweisvariable<br />

stu<strong>die</strong>re()<br />

denke()<br />

schlafe()<br />

Name<br />

stud2<br />

:<br />

null<br />

Die Verweisvariable<br />

hat noch den Wert null<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 17


Folie 43 aus <strong>Kapitel</strong> 5:<br />

Zuweisung von Referenzen auf Objekte<br />

v E<strong>in</strong>e Variable kann nicht nur Werte wie false oder 100 speichern,<br />

sondern auch e<strong>in</strong>en Verweis (“Referenz”, “Addresse”) auf e<strong>in</strong> Objekt.<br />

Student stud1, stud2; // Deklaration von 2 Variablen<br />

stud1 = new Student(); // Erzeugt Objekt vom Typ Student<br />

Nach der Instantiierung<br />

verweist stud1 auf e<strong>in</strong><br />

Objekt vom Typ Student.<br />

stud1<br />

Die andere Variable stud2 kann irgendwann<br />

mal auf e<strong>in</strong> Student-Objekt verweisen, aber<br />

ihre Referenz ist zur Zeit nicht def<strong>in</strong>iert (null).<br />

stud2<br />

Student<br />

stu<strong>die</strong>rt<br />

denkt<br />

schlaeft<br />

stu<strong>die</strong>re()<br />

denke()<br />

schlafe()<br />

true<br />

false<br />

false<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 18


Referenzsemantik <strong>in</strong> Java<br />

v Für Reihungsvariable <strong>und</strong> für alle Objekte von<br />

benutzerdef<strong>in</strong>ierten Klassen gilt <strong>die</strong> Referenzsemantik.<br />

v Bei der Parameterübergabe von Referenzvariablen wird <strong>die</strong><br />

Referenz zur Reihung oder zum Objekt übergeben (call by<br />

reference), nicht e<strong>in</strong>e Kopie (call by value) der ganzen Elemente.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 19


Parameterübergabe bei Methodenaufrufen:<br />

Wertesemantik<br />

Call by Value: Beim Methodenaufruf übergeben wir der Wert des<br />

aktuellen Parameters (z.B. e<strong>in</strong>er Variablen) aus dem aufrufenden<br />

Programm an den formalen Parameter der Methode: Hierbei wird der<br />

Parameter durch e<strong>in</strong>e Kopie des Variablenwertes ersetzt. Zuweisungen an<br />

<strong>die</strong> Kopie haben ke<strong>in</strong>en Effekt auf <strong>die</strong> Variable:<br />

n bekommt den<br />

Wert von Num<br />

public void add1(<strong>in</strong>t n) {<br />

System.out.pr<strong>in</strong>tln("n = " + n);<br />

n = n + 1;<br />

System.out.pr<strong>in</strong>tln("n = " + n);<br />

}<br />

Alle Zuweisungen an den Parameter n <strong>in</strong>nerhalb der Methode add1() s<strong>in</strong>d<br />

lokal, <strong>und</strong> existieren nicht ausserhalb des Methodenaufrufes.<br />

<strong>in</strong>t Num = 5;<br />

System.out.pr<strong>in</strong>tln("Num = " + Num);<br />

add1(Num);<br />

System.out.pr<strong>in</strong>tln("Num = " + Num);<br />

ergibt<br />

Num = 5<br />

n = 5<br />

n = 6<br />

Num = 5<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 20


Parameterübergabe bei Methodenaufrufen: (18.11.2003)<br />

Referenzsemantik<br />

Call by Reference: In <strong>die</strong>sem Fall wird nicht der Wert, sondern <strong>die</strong><br />

Referenz ("Addresse") des aktuellen Parameters (z.B. e<strong>in</strong>er Objektes<br />

oder e<strong>in</strong>er Reihung) e<strong>in</strong>er Methode übergeben. Zuweisungen an das<br />

Objekt existieren auch ausserhalb des Methodenaufrufs.<br />

<strong>in</strong>t[] <strong>in</strong>tArr = { 21, 20, 27, 24, 19 }; // Initialisierung<br />

Sort sorter = new Sort();<br />

sorter.pr<strong>in</strong>t(<strong>in</strong>tArr);<br />

// Drucke<br />

sorter.bubbleSort(<strong>in</strong>tArr);<br />

// Sortiere<br />

sorter.pr<strong>in</strong>t(<strong>in</strong>tArr);<br />

// Drucke noch mal<br />

ergibt<br />

21 20 27 24 19<br />

19 20 21 24 27<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 21


Zusammenfassung: Referenzvariablen <strong>in</strong> Java<br />

v In Java s<strong>in</strong>d Variablen <strong>in</strong> der Regel Referenzvariablen!<br />

– Ausnahme: Variablen e<strong>in</strong>facher Typen wie <strong>in</strong>t, double,<br />

boolean<br />

v Bei der Zuweisung werden nicht <strong>die</strong> referenzierten Objekte kopiert<br />

sondern lediglich <strong>die</strong> Verweise auf <strong>die</strong>se Objekte.<br />

– Es entstehen mehrfache Verweise auf dasselbe Objekt.<br />

– Änderungen über den e<strong>in</strong>en Verweis (über <strong>die</strong> e<strong>in</strong>e Variable)<br />

bee<strong>in</strong>flussen also Objekte, <strong>die</strong> auch über den anderen Verweis (über<br />

<strong>die</strong> andere Variable) erreicht werden.<br />

– Es entsteht also das sogenannnte Aliasnamen-Problem.<br />

v Auch bei der Parameterübergabe (call by value) werden nur Verweise<br />

kopiert, nicht jedoch <strong>die</strong> referenzierten Objekte.<br />

v In Programmiersprachen wie Pascal dagegen werden bei der Zuweisung<br />

von Reihungsvariablen auch <strong>die</strong> Inhalte kopiert.<br />

– Das Referenzkonzept muss dort explizit angefordert werden.<br />

– Z.B. bei der Parameterübergabe <strong>in</strong> Pascal mittels var.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 22


Mehrdimensionale <strong>Reihungen</strong><br />

v Mehrdimensionale <strong>Reihungen</strong> s<strong>in</strong>d <strong>in</strong> Java <strong>Reihungen</strong>, deren Elemente<br />

<strong>Reihungen</strong> s<strong>in</strong>d, deren Elemente wiederum <strong>Reihungen</strong> s<strong>in</strong>d, usw.<br />

v Beispiel: 2-dimensionale<br />

Matrix aus 3 Zeilen <strong>und</strong><br />

4 Spalten ganzer Zahlen:<br />

1 2 3 4<br />

2 4 6 8<br />

3 6 9 12<br />

v Die Matrix wird <strong>in</strong> Java folgendermaßen<br />

deklariert, <strong>in</strong>stantiiert <strong>und</strong> besetzt:<br />

<strong>in</strong>t[][] matrix = new <strong>in</strong>t[3][4];<br />

for (<strong>in</strong>t row = 0; row < 3; row++)<br />

for (<strong>in</strong>t col = 0; col < 4; col++)<br />

matrix[row][col] = (row+1) * (col+1);<br />

v Die entstehenden Reihungsobjekte lassen sich so veranschaulichen:<br />

matrix:<br />

3 6 9 12<br />

2 4 6 8<br />

1 2 3 4<br />

Das Element<br />

matrix[2][2]<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 23


mehrdimensionale <strong>Reihungen</strong> (cont‘d)<br />

v Dasselbe Ergebnis bekommt man, wenn man <strong>die</strong> 3 Zeilen e<strong>in</strong>zeln<br />

<strong>in</strong>stantiiert:<br />

<strong>in</strong>t[][] matrix;<br />

= new <strong>in</strong>t[3][];<br />

for (<strong>in</strong>t row = 0; row < 3; row++){<br />

matrix[row] = new <strong>in</strong>t[4];<br />

} for (<strong>in</strong>t col = 0; col < 4; col++)<br />

matrix[row][col] = (row+1) * (col+1);<br />

}<br />

matrix:<br />

3 6 9 12<br />

2 4 6 8<br />

1 2 3 4<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 24


Dreiecksmatrizen<br />

v Wenn <strong>die</strong> Zeilen 2-dimensionaler <strong>Reihungen</strong> e<strong>in</strong>zeln <strong>in</strong>stantiiert werden<br />

können, müssen sie auch nicht gleiche Länge haben.<br />

v Damit lassen sich z.B. Dreiecksmatrizen darstellen:<br />

<strong>in</strong>t[][] dreieck = new <strong>in</strong>t[3][];<br />

dreieck[0] = new <strong>in</strong>t[1];<br />

dreieck[1] = new <strong>in</strong>t[2];<br />

dreieck[2] = new <strong>in</strong>t[3];<br />

dreieck:<br />

0 0 0<br />

0<br />

0 0<br />

0 0<br />

0 0 0<br />

0<br />

Das Element<br />

dreieck[2][0]<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 25


2-dimensionale <strong>Reihungen</strong><br />

Motivation: Berechne <strong>die</strong> durchschnittliche monatliche<br />

Regenmenge <strong>in</strong> München.<br />

Mit e<strong>in</strong>er 1-dimensionalen Reihung wäre das möglich, aber sehr<br />

kompliziert:<br />

double[] ra<strong>in</strong>fall = new double[365];<br />

E<strong>in</strong>e 2-dimensionale Reihung ist e<strong>in</strong>e Reihung von <strong>Reihungen</strong> (an<br />

array of arrays) ist besser geeignet.<br />

Die erste Reihung s<strong>in</strong>d <strong>die</strong> 12 Monate, <strong>in</strong>diziert von 0 bis 11.<br />

Jeder Monat ist wieder e<strong>in</strong>e Reihung von 31 Tagen, <strong>in</strong>diziert von 0<br />

bis 30.<br />

double[][] ra<strong>in</strong>fall = new double[12][31];<br />

Monats<strong>in</strong>dex<br />

Tages<strong>in</strong>dex<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 26


E<strong>in</strong>e 2-D-Repräsentation<br />

Der Regenfall am 3. Januar ist mit <strong>die</strong>ser Repräsentation<br />

ra<strong>in</strong>fall[0][2] (schlechte Lesbarkeit durch Null-Indizierung).<br />

Wir können <strong>die</strong> Lesbarkeit erhöhen, <strong>in</strong>dem wir e<strong>in</strong>e extra Reihe <strong>und</strong><br />

Spalte erlauben <strong>und</strong> <strong>die</strong> 0-Indizes ignorieren:<br />

Wir ignorieren<br />

<strong>die</strong>se Spalte<br />

double[][] ra<strong>in</strong>fall = new double[13][32];<br />

.<br />

.<br />

.<br />

0,0 0,1 0,2 0,3 ... 0,29 0,30 0,31<br />

1,0 1,1 1,2 1,3 ... 1,29 1,30 1,31 Januar<br />

2,0 2,1 2,2 2,3 ... 2,29 2,30 2,31 Februar<br />

11,0 11,1 11,2 11,3 ... 11,29 11,30 11,31 November<br />

12,0 12,1 12,2 12,3 ... 12,29 12,30 12,31 Dezember<br />

Wir ignorieren <strong>die</strong>se Reihe<br />

Regenfall am 3. Januar<br />

ist jetzt ra<strong>in</strong>fall[1][3]<br />

ra<strong>in</strong>fall[1][5] = 1.15; // Regen für 5. Januar<br />

ra<strong>in</strong>fall[13][32] = 0.15 ; // Reihe <strong>und</strong> Spalte gibt es nicht!<br />

ra<strong>in</strong>fall[11][32] = 1.3; // 32. Spalte gibt es nicht!<br />

ra<strong>in</strong>fall[13][30] = 0.74; // 13. Reihe gibt es nicht!<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 27


Initialisierung e<strong>in</strong>er 2-dimensionalen Reihung <strong>in</strong><br />

e<strong>in</strong>er Methode<br />

Wir benutzen 2 geschachtelte Schleifen, um <strong>die</strong> Reihung zu<br />

<strong>in</strong>itialisieren:<br />

/**<br />

* Initialisiert e<strong>in</strong>e 2-D Reihung<br />

* Vorbed<strong>in</strong>gung: ra<strong>in</strong> ist nicht null<br />

* Nachbed<strong>in</strong>gung: ra<strong>in</strong>[x][y] == 0.0 für alle x,y <strong>in</strong> der Reihung<br />

*/<br />

public void <strong>in</strong>itRa<strong>in</strong>(double[][] ra<strong>in</strong>) {<br />

for (<strong>in</strong>t month = 1; month < ra<strong>in</strong>.length; month++)<br />

for (<strong>in</strong>t day = 1; day < ra<strong>in</strong>[month].length; day++)<br />

ra<strong>in</strong>[month][day] = 0.0;<br />

} // <strong>in</strong>itRa<strong>in</strong>()<br />

Methodenaufruf: Übergibt den Namen der Reihung an <strong>die</strong><br />

Methode:<br />

Die 2-D Reihung als<br />

formaler Parameter<br />

Zwei geschachtelte<br />

Zählschleifen, <strong>die</strong><br />

12 x 31 iterieren<br />

double[][] ra<strong>in</strong>fall = new double[13][32];<br />

<strong>in</strong>itRa<strong>in</strong>(ra<strong>in</strong>fall); // Beispiel e<strong>in</strong>es Methodenaufrufs<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 28


Berechnung des durchschnittlichen täglichen Regens<br />

public double avgDailyRa<strong>in</strong>(double[][] ra<strong>in</strong>) {<br />

double total = 0.0;<br />

for (<strong>in</strong>t month = 1; month < ra<strong>in</strong>.length; month++)<br />

for (<strong>in</strong>t day = 1; day < ra<strong>in</strong>[month].length; day++)<br />

total += ra<strong>in</strong>[month][day];<br />

return total/365;<br />

}<br />

System.out.pr<strong>in</strong>tln("Täglicher Regen: " + avgDailyRa<strong>in</strong>(ra<strong>in</strong>fall));<br />

Methodenaufruf <strong>in</strong>nerhalb e<strong>in</strong>er<br />

Druckanweisung.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 29


Berechnung des durchschnittlichen monatlichen Regens<br />

public double avgRa<strong>in</strong>ForMonth(double[][] ra<strong>in</strong>, <strong>in</strong>t month, <strong>in</strong>t nDays)<br />

{<br />

double total = 0.0;<br />

for (<strong>in</strong>t day = 1; day


<strong>Reihungen</strong> <strong>und</strong> Reihungswerte als Parametertypen<br />

Der Typ des aktuellen Parameters bei e<strong>in</strong>em Methodenaufruf muss<br />

denselben Typ wie der formale Parameter <strong>in</strong> der Methodendef<strong>in</strong>ition haben.<br />

Dies gilt für alle Parameter e<strong>in</strong>schließlich <strong>Reihungen</strong>:<br />

double<br />

double[]<br />

double[][]<br />

ra<strong>in</strong>fall[1][14]: Regenfall vom 14. Januar<br />

ra<strong>in</strong>fall[3]: 1-D-Reihung mit März-Daten<br />

ra<strong>in</strong>fall: Die gesamte 2-D-Reihung<br />

0<br />

1<br />

2<br />

.<br />

.<br />

.<br />

10<br />

11<br />

12<br />

13<br />

0 1 2 ... 31<br />

…...<br />

1.14<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 31<br />

J<br />

F<br />

M<br />

A<br />

M<br />

J<br />

…...<br />

O<br />

N<br />

D


Multidimensionale <strong>Reihungen</strong><br />

E<strong>in</strong>e 3-dimensionale Reihung kann man für <strong>die</strong> Messung von<br />

Regenfällen über mehrere Jahre benutzen.<br />

0<br />

1<br />

2<br />

.<br />

.<br />

.<br />

11<br />

12<br />

13<br />

0 1 2 ... year 0<br />

31<br />

0<br />

1<br />

2<br />

.<br />

.<br />

.<br />

11<br />

12<br />

13<br />

0 1 2 ... year 1<br />

J 31<br />

F<br />

0 1 2 ... year 2<br />

J 31<br />

0<br />

M<br />

F<br />

1<br />

A<br />

M<br />

2<br />

M<br />

A<br />

.<br />

J<br />

M<br />

.<br />

J<br />

J<br />

.<br />

A<br />

J<br />

S<br />

A<br />

O<br />

S<br />

N<br />

O<br />

D<br />

N<br />

11<br />

D<br />

12<br />

13<br />

J<br />

F<br />

M<br />

A<br />

M<br />

J<br />

J<br />

A<br />

S<br />

O<br />

N<br />

D<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 32


E<strong>in</strong>e 3-D-Reihung<br />

v Deklaration der Reihung:<br />

f<strong>in</strong>al <strong>in</strong>t NYEARS = 10;<br />

f<strong>in</strong>al <strong>in</strong>t NMONTHS = 13;<br />

f<strong>in</strong>al <strong>in</strong>t NDAYS = 32;<br />

double[][][] ra<strong>in</strong>fall = new double[NYEARS][NMONTHS][NDAYS];<br />

Initialisierung mit 3 geschachtelten Schleifen:<br />

for (<strong>in</strong>t year = 1; year < ra<strong>in</strong>fall.length; year++) {<br />

for (<strong>in</strong>t month = 1; month < ra<strong>in</strong>fall[year].length; month++) {<br />

for (<strong>in</strong>t day = 1; day < ra<strong>in</strong>fall[year][month].length; day++) {<br />

ra<strong>in</strong>fall[year][month][day] = 0.0;<br />

}<br />

}<br />

}<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 33


Initialisierung von <strong>Reihungen</strong><br />

v Bei kle<strong>in</strong>en <strong>Reihungen</strong>, kann man e<strong>in</strong>en Initialisierungsausdruck<br />

(<strong>in</strong>itializer expression) für <strong>die</strong> Zuweisung von Anfangswerten<br />

verwenden:<br />

2 x 3 Reihung<br />

von <strong>in</strong>t-Werten<br />

Initialisierungsausdruck<br />

<strong>in</strong>t[][] a = { {1, 2, 3}, {4, 5, 6} };<br />

2 x 2 Reihung char [][] c = { {'a', 'b'}, {'c', 'd'} };<br />

von char-Werten.<br />

double [][][] d ={ { {1.0, 2.0}, {3.0, 4.0} },<br />

{ {5.0, 6.0}, {7.0, 8.0} },<br />

{ {9.0, 10.0}, {11.0, 12.0}}<br />

};<br />

3 x 2 x 2 Reihung<br />

von double-Werten.<br />

In Java kann jede Teilreihung e<strong>in</strong>er mehr-dimensionalen Reihung<br />

e<strong>in</strong>e unterschiedliche Länge haben (siehe Dreiecksmatrix Beispiel )!<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 34


Dynamische <strong>Reihungen</strong>: java.util.Vector<br />

v Reguläre <strong>Reihungen</strong> s<strong>in</strong>d auf <strong>die</strong> zum Zeitpunkt der Initialisierung<br />

(statisch) vere<strong>in</strong>barte Größe beschränkt.<br />

Sie können später nicht mehr wachsen oder kle<strong>in</strong>er werden.<br />

v Die java.util.Vector Klasse implementiert e<strong>in</strong>e Reihung von Objekten<br />

(ke<strong>in</strong>e Gr<strong>und</strong>typwerte als Elemente!), <strong>die</strong> auch nach der Initialisierung<br />

(dynamisch) wachsen kann.<br />

public class Vector {<br />

public Vector(<strong>in</strong>t size);<br />

public Vector();<br />

// Konstruktor: Array mit Anfangsgröße<br />

// Konstruktor: Array ohne Anfangsgröße<br />

}<br />

public void addElement(Object obj);<br />

public Object elementAt(<strong>in</strong>t <strong>in</strong>dex);<br />

// Füge obj zum Array dazu<br />

// Hole das bei <strong>in</strong>dex<br />

// gespeicherte Element<br />

public void <strong>in</strong>sertElementAt(Object obj, <strong>in</strong>t <strong>in</strong>dex); // Speicher obj bei<br />

// <strong>in</strong>dex<br />

public <strong>in</strong>t <strong>in</strong>dexOf(Object obj); // Ermittle <strong>in</strong>dex von obj<br />

public void removeElementAt(<strong>in</strong>t <strong>in</strong>dex); // Entferne Element bei <strong>in</strong>dex<br />

public <strong>in</strong>t size(); // Länge des dynamischen Arrays<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 35


Sortierte <strong>Reihungen</strong><br />

v <strong>Reihungen</strong> <strong>die</strong>nen dazu, große Datenmengen zu verwalten.<br />

v Große Datenmengen lassen sich jedoch nicht effizient verwalten,<br />

wenn sie nicht sortiert vorliegen<br />

– Beispiel: Suche nach e<strong>in</strong>em Wort <strong>in</strong> e<strong>in</strong>em Roman vs. Suche<br />

nach e<strong>in</strong>em Wort <strong>in</strong> e<strong>in</strong>em Lexikon<br />

v Voraussetzung, dass man Daten sortieren kann, ist, dass auf dem<br />

Datentyp e<strong>in</strong>e Ordnung def<strong>in</strong>iert ist.<br />

v Programm für den Rest <strong>die</strong>ses Vorlesungsblocks:<br />

– Formale Def<strong>in</strong>ition von Relationen <strong>und</strong> unterschiedlichen<br />

Ordnungen (nach Goos)<br />

– Erste Algorithmen, um <strong>Reihungen</strong> zu sortieren<br />

– E<strong>in</strong> schneller Algorithmus, um <strong>in</strong> sortierten <strong>Reihungen</strong> Elemente<br />

zu f<strong>in</strong>den<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 36


Def<strong>in</strong>ition Relation<br />

v Gegeben seien zwei Mengen M <strong>und</strong> N.<br />

– Die Menge aller Paare (a, b) mit a aus M <strong>und</strong> b aus N heißt<br />

kartesisches Produkt von M <strong>und</strong> N.<br />

– <strong>in</strong> Zeichen: M ¥ N = def { (a, b) | a Œ M Ÿ b Œ N }<br />

v E<strong>in</strong>e (zweistellige) Relation R zwischen den Mengen M <strong>und</strong> N ist e<strong>in</strong>e<br />

Teilmenge des kartesischen Produkts:<br />

– R Õ M ¥ N<br />

РStatt (a,b) ΠR schreiben wir oft a R b (Infix-Schreibweise) <strong>und</strong><br />

sprechen „a steht <strong>in</strong> Relation R zu b“.<br />

v Falls M <strong>und</strong> N <strong>die</strong>selbe Menge s<strong>in</strong>d, d.h. falls gilt R Õ M ¥ M, dann<br />

nennen wir R auch e<strong>in</strong>e (zweistellige) Relation über M.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 37


Eigenschaften von Relationen über M<br />

E<strong>in</strong>e zweistellige Relation R über M (d.h. R Õ M ¥ M)<br />

v heißt reflexiv, wenn für alle a Œ M gilt: a R a<br />

– Beispiele: =, £ <strong>und</strong> Õ s<strong>in</strong>d reflexiv, < <strong>und</strong> Ã s<strong>in</strong>d es nicht.<br />

v heißt irreflexiv, wenn für ke<strong>in</strong> a Œ M gilt: a R a<br />

– Beispiele: < <strong>und</strong> Ã s<strong>in</strong>d irreflexiv, =, £ <strong>und</strong> Õ s<strong>in</strong>d es nicht.<br />

v heißt symmetrisch, wenn aus a R b folgt b R a<br />

– Beispiele: = ist symmetrisch,


Äquivalenzrelation <strong>und</strong> Ordnungen<br />

E<strong>in</strong>e zweistellige Relation R über M (d.h. R Õ M ¥ M)<br />

v heißt Äquivalenzrelation, wenn sie reflexiv, symmetrisch <strong>und</strong> transitiv<br />

ist;<br />

– Beispiele: = ist Äquivalenzrelation,


Sortieralgorithmus<br />

Algorithmus:<br />

1. Wandere über alle Elemente der Reihung, <strong>und</strong> zwar N-1 mal ("Phasen")<br />

2. Vergleiche <strong>die</strong> Nachbarelemente <strong>in</strong> der Reihung (Vergleich: N-1 Paare)<br />

3. Falls das kle<strong>in</strong>er <strong>in</strong>dizierte Element größer ist als das größer <strong>in</strong>dizierte Element<br />

4. Vertausche <strong>die</strong> beiden Elemente<br />

21 20 27 24 19 // Die unsortierte Reihung<br />

[20 21] 27 24 19 // Anfang Phase 1: Vergleiche Nachbarelemente<br />

20 [21 27] 24 19 // Vertausche,falls notwendig,geh weiter<br />

20 21 [24 27] 19 // Vertausche,falls notwendig,geh weiter<br />

20 21 24 [19 27]<br />

20 21 24 19 |27 // Ende Phase 1: 27 ist jetzt an der Spitze<br />

[20 21] 24 19 27 // Anfang Phase 2<br />

…<br />

20 19 21 |24 27 // Ende Phase 2: 24 hat jetzt se<strong>in</strong>en Platz<br />

….<br />

|19 20 21 24 27 // End Phase 4: Das ganze Feld ist sortiert<br />

Seifenblasen-Algorithmus (Bubblesort algorithm):<br />

Bei jeder R<strong>und</strong>e (auch Phase genannt) durch <strong>die</strong> Reihung lassen wir das<br />

größte noch nicht sortierte Element ans Ende "blubbern".<br />

Für e<strong>in</strong> Feld mit N Elementen werden N-1 Phasen benötigt.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 40


Die Idee h<strong>in</strong>ter dem Bubblesort<br />

Swap: 0<br />

Comp: 0<br />

Swap: 0<br />

Comp:1<br />

Swap:1<br />

Comp:2<br />

Swaps:25 Swaps:8 Swaps:9<br />

Comp: 45<br />

Comp:10 9<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 42


Wie vertauschen wir 2 Elemente <strong>in</strong> e<strong>in</strong>er Reihung?<br />

Beispiel: Nehmen wir an, wir haben <strong>die</strong> Reihung arr mit der<br />

Belegung: 1 4 2 8<br />

Wir wollen jetzt 4 and 2 vertauschen. Sei pair der Index <strong>in</strong> der<br />

Reihung, wir setzen also pair = 2; Los geht's:<br />

arr[pair-1] = arr[pair];<br />

arr[pair] = arr[pair-1];<br />

Wir bekommen: 1 2 2 8<br />

So e<strong>in</strong>fach geht es also nicht.<br />

Der Trick: E<strong>in</strong>e temporäre Variable muss deklariert werden, wenn man<br />

<strong>die</strong> Werte von zwei Variablen vertauschen will:<br />

<strong>in</strong>t temp = arr[pair-1];<br />

Wir erwarten: 1 2 4 8<br />

// Speichere den ersten Wert <strong>in</strong> temp<br />

arr[pair-1] = arr[pair]; // Überschreibe den ersten Wert mit<br />

// dem zweiten Wert<br />

arr[pair] = temp; // Überschreibe den zweiten Wert mit<br />

// temp (das den ersten Wert<br />

Ergebnis: 1 2 4 8<br />

// zwischengespeichert hat)!<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 43


Java-Implementation von Bubblesort mit Tausch<br />

<strong>in</strong>t[] arr = { 1, 4, 2, 8};<br />

// E<strong>in</strong>e vor<strong>in</strong>itialisierte Reihung von Werten<br />

for (<strong>in</strong>t pass = 1; pass < arr.length; pass++) {<br />

// Für jede R<strong>und</strong>e<br />

for (<strong>in</strong>t pair = 1; pair arr[pair]) { // Vergleiche <strong>die</strong> Werte<br />

// <strong>und</strong> vertausche, falls<br />

// notwendig<br />

<strong>in</strong>t temp = arr[pair-1]; // Speichere den ersten Wert <strong>in</strong> temp<br />

arr[pair-1] = arr[pair]; // Überschreibe den ersten Wert mit<br />

// dem zweiten Wert<br />

arr[pair] = temp; // Überschreibe den zweiten Wert mit<br />

// temp (das den ersten Wert<br />

// zwischengespeichert hat)!<br />

} // Ende if<br />

} // Ende for pair<br />

} // Ende for pass<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 44


Implementation von bubbleSort() als Dienst<br />

Parameter vom Typ Array s<strong>in</strong>d Referenzvariablen, d.h. <strong>die</strong><br />

Parameterübergabe erfolgt per Call-by-Reference: Änderungen, <strong>die</strong> an<br />

Reihungsvariablen <strong>in</strong> der Methode gemacht werden, s<strong>in</strong>d außerhalb der<br />

Methode sichtbar.<br />

Der formale Parameter ist als Reihung<br />

(<strong>in</strong>t[] arr) spezifiziert<br />

/**<br />

* Ziel: Sortiere <strong>die</strong> Werte von arr <strong>in</strong> aufsteigender Reihenfolge<br />

* Vorbed<strong>in</strong>gung: arr ist nicht null.<br />

* Nachbed<strong>in</strong>gung: Die Werte arr[0]...arr[arr.length-1] s<strong>in</strong>d <strong>in</strong><br />

* aufsteigender Reihenfolge sortiert.<br />

*/<br />

public void bubbleSort(<strong>in</strong>t[] arr) {<br />

for (<strong>in</strong>t pass = 1; pass < arr.length; pass++)<br />

Beim Methodenaufruf wird nur der Name<br />

des aktuellen Parameters benötikz<br />

// Für jede R<strong>und</strong>e<br />

for (<strong>in</strong>t pair = 1; pair < arr.length; pair++) // Für jedes Paar<br />

if (arr[pair-1] > arr[pair]) { // Vergleiche <strong>die</strong> Werte<br />

<strong>in</strong>t temp = arr[pair-1]; // <strong>und</strong> vertausche, falls<br />

arr[pair-1] = arr[pair]; // notwendig<br />

arr[pair] = temp;<br />

Aufrufendes Programm:<br />

} // if<br />

<strong>in</strong>t[] myArr = {21, 20, 27, 24, 19};<br />

} // bubbleSort()<br />

bubbleSort(myArr);<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 45


Aufruf des "Dienstes" Bubblesort<br />

public class Sort {<br />

public void pr<strong>in</strong>t(<strong>in</strong>t[] arr) {<br />

for (<strong>in</strong>t k = 0; k < arr.length; k++) // Für jedes Element<br />

System.out.pr<strong>in</strong>t( arr[k] + " \t "); // Drucke es<br />

System.out.pr<strong>in</strong>tln();<br />

} // pr<strong>in</strong>t()<br />

public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />

<strong>in</strong>t[] myArr = { 21, 20, 27, 24, 19 };<br />

Sort sorter = new Sort();<br />

sorter.pr<strong>in</strong>t(myArr);<br />

sorter.bubbleSort(myArr);<br />

sorter.pr<strong>in</strong>t(myArr);<br />

} // ma<strong>in</strong>()<br />

} // Sort public void bubbleSort(<strong>in</strong>t[] arr) {<br />

for (<strong>in</strong>t pass = 1; pass < arr.length; pass++)<br />

for (<strong>in</strong>t pair = 1; pair < arr.length;<br />

pair++)<br />

if (arr[pair-1] > arr[pair]) {<br />

<strong>in</strong>t temp = arr[pair-1];<br />

arr[pair-1] = arr[pair];<br />

arr[pair] = temp;<br />

} // if<br />

} // bubbleSort()<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 46


Bubblesort kann <strong>in</strong> 4 Zeilen geschrieben werden<br />

private void swap(<strong>in</strong>t one, <strong>in</strong>t two, <strong>in</strong>t[] arr) {<br />

<strong>in</strong>t temp = arr[one]; // Zwischenspeicher für arr[one]<br />

arr[one] = arr[two];<br />

arr[two] = temp;<br />

}<br />

// In Swap übergebe ich <strong>die</strong> Array-Indizes,<br />

// nicht <strong>die</strong> Array-Elementwerte<br />

public void bubbleSort(<strong>in</strong>t[] arr) {<br />

for (<strong>in</strong>t pass = 1; pass < arr.length; pass++) // Für jede R<strong>und</strong>e<br />

for (<strong>in</strong>t pair = 1; pair < arr.length; pair++)// Für jedes Paar<br />

if (arr[pair-1] > arr[pair] // Vergleiche <strong>die</strong> Werte<br />

swap(pair-1, pair, arr); // Swap, falls notwendig<br />

}<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 47


Komplexität von Algorithmen<br />

v Bubblesort lässt sich schnell implementieren, arbeitet aber sehr langsam,<br />

vor allem, wenn <strong>die</strong> Anzahl der Elemente größer wird.<br />

v Es gibt schnellere Sortieralgorithmen als Bubblesort.<br />

– Selectionsort, Insertionsort, Quicksort, Mergesort<br />

v Wenn wir verschiedene Algorithmen haben, ist es nützlich, <strong>die</strong>se<br />

Algorithmen bezüglich ihrer Kosten zu vergleichen.<br />

v Arten von Kosten:<br />

– Programmieraufwand (sehr ger<strong>in</strong>g bei Bubblesort)<br />

– Ausbildungsaufwand für Programmierer<br />

– Anschaffungskosten für Rechner <strong>und</strong> Software<br />

– Rechenzeit, Speicherplatzbedarf<br />

v Beim Vergleichen von Algorithmen konzentrieren wir uns auf<br />

Rechenzeit <strong>und</strong> Speicherplatzbedarf <strong>und</strong> vernachlässigen Faktoren, <strong>die</strong><br />

von der Leistungsfähigkeit des Rechners oder der Programmiersprache<br />

abhängen.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 48


2 Arten von Komplexität, 3 Fallunterscheidungen<br />

v Zeitkomplexität: Wieviele Schritte muss e<strong>in</strong> Algorithmus durchführen,<br />

um N E<strong>in</strong>gabedaten zu verarbeiten?<br />

v Platzkomplexität: Wieviel Speicherplatz braucht e<strong>in</strong> Algorithmus, um<br />

N E<strong>in</strong>gabedaten zu verarbeiten?<br />

v Im folgenden beschränken wir uns auf <strong>die</strong> Zeitkomplexität.<br />

v Wir müssen trotzdem folgende Fälle unterscheiden:<br />

– Anzahl der Schritte im schlechtesten Fall (worst case)<br />

– Beispiel: Die Reihung ist völlig unsortiert<br />

– Anzahl der Schritte im besten Fall (best case)<br />

– Beispiel: Die Reihung ist bereits sortiert<br />

– Anzahl der Schritte im durchschnittlichen Fall (average case)<br />

– Beispiel: Die Reihung ist zur Hälfte sortiert.<br />

v Wenn wir von nun an den Begriff Komplexität alle<strong>in</strong> verwenden,<br />

me<strong>in</strong>en wir gewöhnlich Zeitkomplexität im schlechtesten Fall.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 49


E<strong>in</strong>flussfaktoren für Zeitkomplexität<br />

v Wir nehmen an, dass nur Zuweisungen, Vergleiche,<br />

Inkrementierungen <strong>und</strong> Multiplikationen Zeit kosten.<br />

v Wir nehmen an, dass <strong>die</strong> Deklaration von Variablen <strong>und</strong> Allokation<br />

von Speicherplatz ke<strong>in</strong>e Zeit kostet.<br />

v Wir bestimmen deshalb <strong>in</strong> Abhängigkeit von der E<strong>in</strong>gabe n nur<br />

– Z(n): Die Anzahl der Zuweisungen<br />

– V(n): Die Anzahl der Vergleiche<br />

– M(n): Die Anzahl der Multiplikationen<br />

– I(n): Die Anzahl der Inkrementierungen<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 51


Komplexitätsüberlegungen für den Bubblesort:<br />

v Wir haben ke<strong>in</strong>e Multiplikationen.<br />

v Die Anzahl der Inkrementierungen der Schleifenvariablen <strong>und</strong><br />

Vergleiche zur Schleifenterm<strong>in</strong>ierung vernachlässigen wir hier.<br />

v Die Komplexität von Bubblesort wird dann durch 2 Arten von<br />

Operationen bestimmt:<br />

– V(n) = Anzahl der Vergleiche zwischen Elementen<br />

– T(n) = Anzahl der Tauschoperationen (swap) von Elementen<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 52


Komplexitätsüberlegungen für Bubblesort<br />

v Anzahl der Vergleichsoperationen V:<br />

– Bei n =10 s<strong>in</strong>d <strong>in</strong> der ersten R<strong>und</strong>e 9 Vergleiche, <strong>in</strong> der zweiten<br />

R<strong>und</strong>e 8 Vergleiche, usw., bis zu 1 Vergleich <strong>in</strong> der letzten R<strong>und</strong>e:<br />

9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 45<br />

– Allgeme<strong>in</strong> V(n) = (n-1) + (n-2) + …. 1 = n*(n-1)/2<br />

– Bei großem n ist n*(n-1)/2 ungefähr n 2 /2, also<br />

u V(n) ~ n 2 /2<br />

v Anzahl der Tauschoperationen:<br />

– E<strong>in</strong> Tausch f<strong>in</strong>det nur statt, wenn das erste Element größer als das<br />

zweite Element ist. E<strong>in</strong> Tausch T besteht aus 3 Zuweisungen Z<br />

– Wenn <strong>die</strong> Datenverteilung zufällig ist, dann können wir annehmen,<br />

dass e<strong>in</strong> Tausch ungefähr <strong>in</strong> der Hälfte aller Fälle notwendig ist.<br />

u T(n) ~ n 2 /4<br />

u Z(n) ~ 3 * n 2 /4<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 53


Komplexität des Bubblesorts 11/20/03<br />

v Anzahl aller Operationen <strong>in</strong> Bubblesort ~ n 2 /2 + 3*n 2 /4<br />

– Die Anzahl der Vergleichsoperationen <strong>und</strong> Zuweisungen ist also<br />

proportional zu n 2.<br />

v Bei asymptotischen Komplexitätsberechnungen können wir <strong>die</strong><br />

Konstanten weglassen.<br />

v Bubblesort hat somit <strong>die</strong> Komplexität O( n 2 ).<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 54


Allgeme<strong>in</strong>e Beobachtungen zur Komplexität<br />

v Geschachtelte Schleifen haben oft Laufzeitkomplexität O( n 2 ):<br />

– Die äußere Schleife exekutiert n mal, <strong>die</strong> <strong>in</strong>nere für jeden Zyklus<br />

der äußeren Schleife n mal (oder vielleicht n divi<strong>die</strong>rt durch e<strong>in</strong>e<br />

Konstante).<br />

Das ergibt dann ungefähr n*n Operationen, oder O( n 2 ).<br />

v Weitere e<strong>in</strong>fache Sortieralgorithmen mit O( n 2 )-Komplexität:<br />

– Selectionsort<br />

– Insertionsort<br />

v O( n 2 ) ist für das <strong>Sortieren</strong> e<strong>in</strong>e schlechte Komplexität, wenn <strong>die</strong><br />

Anzahl der Elemente sehr groß ist. In <strong>die</strong>sem Fall brauchen wir<br />

Algorithmen, <strong>die</strong> e<strong>in</strong>e bessere Laufzeitkomplexität haben.<br />

v Schnellere Sortieralgorithmen mit O(n*log n)<br />

u Mergesort<br />

u Quicksort<br />

Heute<br />

nach <strong>Kapitel</strong> funktionale Programmierung<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 55


Komplexität: Theorie <strong>und</strong> Praxis<br />

v Die Ordnung von f, geschrieben O(f(n)) ist e<strong>in</strong>e Abschätzung für<br />

das Wachstum von Funktionen (z.b. für <strong>die</strong> Laufzeit e<strong>in</strong>es<br />

Algorithmus)<br />

– d.h. <strong>die</strong> Komplexitätsüberlegungen gelten für den Fall n Æ µ<br />

v Das Laufzeitverhalten von zwei Algorithmen, auch wenn sie <strong>die</strong><br />

<strong>die</strong>selbe Laufzeitkomplexität haben, kann sehr wohl grosse<br />

Unterschiede bei praktischen Werten für <strong>die</strong> Anzahl der<br />

E<strong>in</strong>gabewerte zeigen.<br />

v Beispiel:<br />

– Verschiedene Implementationen für <strong>die</strong> Matrixmultiplikation<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 56


Beispiel: Matrixmultiplikation<br />

v Gr<strong>und</strong>idee des Algorithmus: Reihen mit Spalten multiplizieren<br />

v allgeme<strong>in</strong>:<br />

/* ijk */<br />

for (i = 0; i < n; i++) {<br />

for (j = 0; j < n; j++) {<br />

sum = 0.0;<br />

for (k = 0; k < n; k++)<br />

sum += a[i][k]*b[k][j];<br />

c[i][j] = sum;<br />

}<br />

}<br />

v Komplexität für Matrizenmultiplikation ist O(n 3 )<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 57


Zwei Algorithmen für <strong>die</strong> Matrixmultiplikation<br />

/* ijk */<br />

for (i = 0; i < n; i++) {<br />

for (j = 0; j < n; j++) {<br />

sum = 0.0;<br />

for (k = 0; k < n; k++)<br />

sum += A[i][k]*B[k][j];<br />

C[i][j] = sum;<br />

}<br />

}<br />

/* kij */<br />

for (k = 0; k < n; k++)<br />

for (i = 0; i < n; i++) {<br />

sum = 0.0;<br />

for (j = 0; j < n; j++)<br />

sum += A[i][k]*B[k][j];<br />

C[i][j] = sum;<br />

}<br />

}<br />

Ergeben <strong>die</strong> beiden Algorithmen dasselbe Resultat?<br />

Ja!<br />

Haben beide Algorithmen <strong>die</strong>selbe Laufzeitkomplexität?<br />

Ja!<br />

Wie sieht es mit der aktuellen Laufzeit aus?<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 58


Laufzeit der Implementation (Reihenfolge i-j-k)<br />

Zeit<br />

/* ijk */<br />

for (i = 0; i < n; i++) {<br />

for (j = 0; j < n; j++) {<br />

sum = 0.0;<br />

for (k = 0; k < n; k++)<br />

sum += A[i][k]*B[k][j];<br />

C[i][j] = sum;<br />

}<br />

}<br />

Grösse der<br />

Matrix<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 59


Alternative Implementation (Reihenfolge k-i-j)<br />

/* kij */<br />

for (k = 0; k < n; k++)<br />

for (i = 0; i < n; i++) {<br />

sum = 0.0;<br />

for (j = 0; j < n; j++)<br />

sum += A[i][k]*B[k][j];<br />

C[i][j] += sum;<br />

}<br />

}<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 60


Laufzeitverhalten von verschiedenen Implementationen<br />

jki<br />

kji<br />

ijk<br />

jik<br />

Warum s<strong>in</strong>d <strong>die</strong><br />

kij <strong>und</strong> ikj<br />

Implementationen<br />

so schnell?<br />

kij<br />

ikj<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 61


Interpretation der Ergebnisse<br />

v Trotz der gleichen Anzahl von Operationen <strong>in</strong> jedem Algorithmus<br />

sehen wir sehr unterschiedliche Laufzeiten<br />

– kij ist bis zu 3 mal schneller als kji bei gleicher Matrixgröße<br />

v Für Multiplikationen von kle<strong>in</strong>en Matrizen ist der Effekt nicht zu<br />

beobachten, sehr wohl aber bei großen Matrizen<br />

– Bei n = 400 braucht kij nur 2.5 sek, kji braucht 8 sek<br />

v Gr<strong>und</strong> für <strong>die</strong> unterschiedlichen Laufzeiten:<br />

– Größe des Prozessorcaches <strong>und</strong> des Speicherbedarfs der<br />

<strong>in</strong>neren Schleife<br />

v Lektion: Auch beim Programmieren mit höherer<br />

Programmiersprachen muss man <strong>die</strong> Rechnerarchitektur kennen.<br />

=> Technische <strong>Informatik</strong>, TGI Praktikum<br />

=> Mehr darüber auch im <strong>Kapitel</strong> über masch<strong>in</strong>ennahe<br />

Programmierung (Info II)<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 64


E<strong>in</strong> anderer Sortieralgorithmus:<br />

<strong>Sortieren</strong> nach Auswahl (Selectionsort)<br />

v Gr<strong>und</strong>pr<strong>in</strong>zip:<br />

– Partitioniere <strong>die</strong> Reihung <strong>in</strong> zwei Teilreihungen F <strong>und</strong> S.<br />

Solange es Elemente <strong>in</strong> der Reihung F gibt, f<strong>in</strong>de <strong>in</strong> F das kle<strong>in</strong>ste<br />

Element, <strong>und</strong> überführe es ans Ende der Reihung S.<br />

v Algorithmus für Selectionsort (<strong>in</strong> Pseudocode):<br />

1. Initialisierung: Setze S auf null<br />

2. Trivialfall: Wenn F == null, dann ist S das Ergebnis<br />

3. Reduktion:<br />

F<strong>in</strong>de das M<strong>in</strong>imum <strong>in</strong> F:<br />

a = select(F)<br />

Hänge a an das Ende von S: appendElem(S, a)<br />

Entferne a aus F: deleteElem(F, a)<br />

4. Iteration: Gehe nach 2<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 65


Gr<strong>und</strong>idee des Algorithmus<br />

S<br />

F<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 66


Selectionsort<br />

Animation<br />

public void selectionSort() {<br />

<strong>in</strong>t outer, <strong>in</strong>ner, m<strong>in</strong>;<br />

for(outer = 0; outer < nElems-1; outer++){ // Äussere Schleife<br />

m<strong>in</strong> = outer;<br />

// Bestimme Index des M<strong>in</strong>imums<br />

for(<strong>in</strong>ner = outer+1; <strong>in</strong>ner < nElems; <strong>in</strong>ner++){ // Innnere Schleife<br />

if(a[<strong>in</strong>ner] < a[m<strong>in</strong>]) // Wenn a[m<strong>in</strong>] größer ist,<br />

m<strong>in</strong> = <strong>in</strong>ner;<br />

// dann haben wir e<strong>in</strong> neues M<strong>in</strong><br />

}<br />

swap(outer, m<strong>in</strong>, a); // Vertausche <strong>die</strong> Elemente<br />

} // end for(outer)<br />

} // end selectionSort()<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 67


Komplexität von Selectionsort<br />

v Selectionsort führt <strong>die</strong>selbe Anzahl von Vergleichen aus wie<br />

Bubblesort.<br />

v Für großes n dom<strong>in</strong>ieren <strong>die</strong> Vergleichsoperationen, so dass auch<br />

Selectionsort <strong>die</strong> Komplexität O(n 2 ) hat.<br />

v Selectionsort führt im allgeme<strong>in</strong>en wesentlich weniger<br />

Tauschoperationen aus (e<strong>in</strong>e pro Durchlauf der äußeren Schleife).<br />

v Beispiel:<br />

– Für 100 Datenelemente werden 4950 Vergleiche benötigt, aber<br />

nur 100 Tauschoperationen.<br />

v Deshalb ist Selectionsort im allgeme<strong>in</strong>en schneller als Bubblesort.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 68


Noch e<strong>in</strong> Sortieralgorithmus: Insertionsort<br />

v Insertionsort beruht auf der Idee, dass e<strong>in</strong> Teil der Reihung bereits<br />

partiell sortiert ist.<br />

v Wir entnehmen uns e<strong>in</strong> Element aus der noch nicht sortierten<br />

Reihung <strong>und</strong> nennen es das „markierte Element“.<br />

v Wir sortieren dann das markierte Element an der Stelle im partiell<br />

sortierten Teil e<strong>in</strong>, wo es von der Größe her h<strong>in</strong>gehört.<br />

– Um das zu ermöglichen, müssen wir Platz für das markierte<br />

Element machen.<br />

– Wir tun <strong>die</strong>s, <strong>in</strong> dem wir e<strong>in</strong>ige bereits sortierte Elemente nach<br />

rechts schieben, <strong>und</strong> zwar <strong>die</strong>, <strong>die</strong> größer als das markierte<br />

Element s<strong>in</strong>d.<br />

– Um Platz für <strong>die</strong>se Verschiebung zu haben, nehmen wir das<br />

markierte Element temporär aus der Reihung (<strong>in</strong> e<strong>in</strong>e temporäre<br />

Variable).<br />

v Wir term<strong>in</strong>ieren den Sortiervorgang, wenn der nicht sortierte Teil der<br />

Reihung leer ist.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 69


Die Idee h<strong>in</strong>ter<br />

Insertionsort<br />

Animation<br />

Partiell sortiert<br />

M<br />

Partiell sortiert<br />

"leer"<br />

temp<br />

Partiell sortiert<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 70


Implementation von Insertionsort<br />

public void <strong>in</strong>sertionSort(double[] a) {<br />

<strong>in</strong>t <strong>in</strong>, out;<br />

}<br />

for (out = 1; out < nElems; out++) { // out ist <strong>in</strong>dex des<br />

// markierten Elements<br />

double temp = a[out]; // "entferne" markiertes Element<br />

<strong>in</strong> = out;<br />

// start das Verschieben:<br />

while(<strong>in</strong> > 0 && a[<strong>in</strong>-1] > temp) { // Solange Elemente<br />

// größer,<br />

a[<strong>in</strong>] = a[<strong>in</strong>-1]; // schiebe Elemente nach rechts<br />

<strong>in</strong> = <strong>in</strong>-1; // gehe e<strong>in</strong>e Position nach l<strong>in</strong>ks<br />

}<br />

a[<strong>in</strong>] = temp; // Setze das markierte Element e<strong>in</strong><br />

}<br />

Durchschnittliche Laufzeitkomplexität<br />

von Insertionsort<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 71


Wiederholung: E<strong>in</strong>flussfaktoren für<br />

Zeitkomplexität<br />

v Wir bestimmen <strong>in</strong> Abhängigkeit von der E<strong>in</strong>gabe n<br />

– Z(n): Die Anzahl der Zuweisungen<br />

– V(n): Die Anzahl der Vergleiche<br />

– M(n): Die Anzahl der Multiplikationen<br />

– I(n): Die Anzahl der Inkrementierungen<br />

v Wir unterscheiden folgende Fälle :<br />

– Anzahl der Schritte im schlechtesten Fall (worst case)<br />

– Beispiel: Die Reihung ist völlig unsortiert<br />

– Anzahl der Schritte im besten Fall (best case)<br />

– Beispiel: Die Reihung ist bereits sortiert<br />

– Anzahl der Schritte im durchschnittlichen Fall (average case)<br />

– Beispiel: Die Reihung ist zur Hälfte sortiert.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 72


Komplexität von Insertionsort (durchschnittlicher Fall)<br />

v In der ersten R<strong>und</strong>e wird nur e<strong>in</strong> Element verglichen, <strong>in</strong> der<br />

zweiten R<strong>und</strong>e höchstens zwei Elemente.<br />

v In der letzten R<strong>und</strong>e haben wir maximal n-1 Vergleiche:<br />

– V(n) = 1+2+3….+n-1= n*(n-1)/2<br />

v Im durchschnittlichen Fall werden höchstens <strong>die</strong> Hälfte der<br />

Elemente <strong>in</strong> jeder R<strong>und</strong>e vertauscht, also n*(n-1)/4<br />

v Für jeden Tausch brauchen wir 3 Operationen:<br />

– Z(n) ~ 3 * n 2 /4<br />

v Anzahl der Operationen <strong>in</strong> Insertionsort also ~ n 2 /4 + 3*n 2 /4<br />

v Insertionsort hat somit auch <strong>die</strong> Komplexität O( n 2 ).<br />

v Bei kle<strong>in</strong>em n ist Insertionsort zweimal schneller als Bubblesort<br />

(da weniger Kopien) <strong>und</strong> leicht schneller als Selectionsort.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 73


Vorteil von Insertionsort bei sortierten <strong>Reihungen</strong><br />

v Wenn <strong>die</strong> Daten sortiert s<strong>in</strong>d, wird <strong>die</strong> E<strong>in</strong>trittsbed<strong>in</strong>gung <strong>in</strong> <strong>die</strong><br />

While-Schleife (while(<strong>in</strong> > 0 && a[<strong>in</strong>-1] > temp))<br />

fast nie wahr.<br />

v In <strong>die</strong>sem Fall wird <strong>in</strong> der äußeren Schleife nur e<strong>in</strong>e Anweisung<br />

exekutiert.<br />

v Bei sortierten <strong>Reihungen</strong> ist <strong>die</strong> Komplexität von Insertionsort<br />

somit nur O(n).<br />

v Falls <strong>die</strong> Daten sortiert s<strong>in</strong>d, läuft Insertionsort also <strong>in</strong> O(n).<br />

Merken: Insertionsort ist e<strong>in</strong>e gute Sortiermethode, wenn <strong>die</strong> zu<br />

sortierende Reihung bereits weitgehend vorsortiert ist.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 74


Sequentieller Suchalgorithmus für <strong>Reihungen</strong><br />

Problem: Suche <strong>in</strong> e<strong>in</strong>er nichtsortierten Reihung a nach e<strong>in</strong>em<br />

bestimmten Wert key.<br />

Idee des Algorithmus: Da <strong>die</strong> Reihung a nicht sortiert ist, müssen<br />

wir e<strong>in</strong>e sogenannte sequentielle Suche durchführen.<br />

public <strong>in</strong>t sequentialSearch(<strong>in</strong>t[] a, <strong>in</strong>t key) {<br />

for (<strong>in</strong>t k = 0; k < a.length; k++)<br />

if (a[k] == key)<br />

return k;<br />

return -1; // Nicht gef<strong>und</strong>en<br />

} // sequentialSearch()<br />

Die Suche war nicht<br />

erfolgreich.<br />

Sobald der Wert gef<strong>und</strong>en ist,<br />

können wir zum Aufrufer<br />

zurückkehren.<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 76


Komplexität von sequentieller Suche<br />

v Die Suche nach e<strong>in</strong>em Element <strong>in</strong> e<strong>in</strong>er ungeordneten Reihung mit<br />

n Elementen ist<br />

– im schlechtesten Fall: V(n) = n<br />

– im durchschnittlichen Fall: V(n) = n/2<br />

– im besten Fall: V(n) = 1<br />

v Komplexität für sequentielle Suche: O(n)<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 77


Implementation von b<strong>in</strong>ärer Suche<br />

Algorithmus: low <strong>und</strong> high zeigen auf das erste <strong>und</strong> letzte Element<br />

der Teilreihung (subarray), <strong>und</strong> mid zeigt immer auf den derzeitigen<br />

Mittelpunkt <strong>in</strong> der Reihung oder Teilreihung.<br />

/**<br />

* Vorbed<strong>in</strong>gung: a ist aufsteigend sortierte Reihung von <strong>in</strong>t<br />

* Nachbed<strong>in</strong>gung: Ergebnis ist -1 oder k, wobei a[k] == key<br />

*/<br />

Wenn low > high, dann ist<br />

public <strong>in</strong>t b<strong>in</strong>arySearch(<strong>in</strong>t[] a, <strong>in</strong>t key) { der Schlüssel nicht <strong>in</strong> der<br />

<strong>in</strong>t low = 0; // Initialisierung<br />

Reihung.<br />

<strong>in</strong>t high = a.length - 1;<br />

while (low high: Suche erfolglos<br />

low bzw. high anpassen, um <strong>die</strong><br />

Reihung <strong>in</strong> 2 Hälften zu schneiden<br />

Code<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 79


Noch e<strong>in</strong> Beispiel<br />

Wir suchen nach Zahl 8<br />

Erste Iteration:<br />

key = 8;<br />

low = 0; high = 9;<br />

mid = 4;<br />

a[4] == 5<br />

Zweite Iteration:<br />

key = 8;<br />

low = 5; high = 9;<br />

mid = 7;<br />

a[7] == 8<br />

1 2 3 4<br />

public <strong>in</strong>t b<strong>in</strong>arySearch(<strong>in</strong>t[] a, <strong>in</strong>t key) {<br />

<strong>in</strong>t low = 0;<br />

<strong>in</strong>t high = a.length - 1;<br />

while (low


Komplexität von b<strong>in</strong>ärer Suche<br />

v L<strong>in</strong>eare Suche läuft auf<br />

beliebigen <strong>Reihungen</strong><br />

v B<strong>in</strong>äre Suche braucht e<strong>in</strong>e<br />

sortierte Reihung<br />

v Bei e<strong>in</strong>er Reihung von bis<br />

zu n Elementen brauchen<br />

wir höchstens log 2 (n)<br />

Vergleiche<br />

v Die Komplexität von<br />

b<strong>in</strong>ärer Suche für sortierte<br />

<strong>Reihungen</strong> ist also<br />

O(log 2 (n)).<br />

max. Anzahl von<br />

Elementen n<br />

<strong>in</strong> der Reihung<br />

1<br />

2<br />

4<br />

8<br />

16<br />

32<br />

64<br />

128<br />

256<br />

512<br />

513<br />

1024<br />

2<br />

log 2<br />

(n)<br />

max. Anzahl<br />

von Teilungen<br />

log 2<br />

(n)<br />

2 0<br />

0<br />

2 1<br />

1<br />

2 2<br />

2<br />

2 3<br />

3<br />

2 4<br />

4<br />

2 5<br />

5<br />

2 6<br />

6<br />

2 7<br />

7<br />

2 8<br />

8<br />

2 9<br />

9<br />

2 10<br />

10<br />

2 10 10<br />

Copyright 2003 Bernd Brügge, Christian Herzog E<strong>in</strong>führung <strong>in</strong> <strong>die</strong> <strong>Informatik</strong> I, TUM W<strong>in</strong>tersemester 2003/04 <strong>Kapitel</strong> 6, Folie 82

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!