Algorithmen und Datenstrukturen (f¨ur...

Post on 10-Sep-2019

3 views 0 download

Transcript of Algorithmen und Datenstrukturen (f¨ur...

Algorithmen und Datenstrukturen (fur ET/IT)Wintersemester 2012/13

Dr. Tobias Lasser

Computer Aided Medical ProceduresTechnische Universitat Munchen

Organisatorisches

Nachste Woche keine Vorlesung!

Es finden nachste Woche keine Vorlesungen statt!

• Mittwoch, 31. Oktober 2012: FVV(Fachschaftsvollversammlung)

• Donnerstag, 1. November 2012: Feiertag (Allerheiligen)

Der Ubungsbetrieb (Zentralubung, Montag 29. Oktober 2012,sowie die Fragestunden, Freitag, 2. November 2012) findet statt!

2

Wiederholung letzte Vorlesung

Ganze Zahlen in C, C++

Ganze Zahlen in C, C++

• 8 Bits: unsigned char {0, . . . , 255}signed char {−128, . . . , 127}

• 16 Bits: unsigned short {0, . . . , 65535}signed short {−32768, . . . , 32767}

• 32 Bits: unsigned long {0, . . . , 232 − 1}signed long {−232, . . . , 232 − 1}

• 64 Bits: unsigned long long {0, . . . , 264 − 1}signed long long {−264, . . . , 264 − 1}

• signed kann weggelassen werden (ausser bei char!)

• unsigned int und signed int sind je nach System 16, 32oder 64 Bit

11

3

Wiederholung letzte Vorlesung

Ganze Zahlen in C, C++

Ganze Zahlen in C, C++

• 8 Bits: unsigned char {0, . . . , 255}signed char {−128, . . . , 127}

• 16 Bits: unsigned short {0, . . . , 65535}signed short {−32768, . . . , 32767}

• 32 Bits: unsigned long {0, . . . , 232 − 1}signed long {−232, . . . , 232 − 1}

• 64 Bits: unsigned long long {0, . . . , 264 − 1}signed long long {−264, . . . , 264 − 1}

• signed kann weggelassen werden (ausser bei char!)

• unsigned int und signed int sind je nach System 16, 32oder 64 Bit

11

Floating Point Zahlen II

V Exponent E Mantisse M

23 Bit8 Bit 32 Bit float

64 Bit double52 Bit11 Bit

1 Bit

1 Bit

• wissenschaftliche Darstellung mit Basis 2

f = (−1)V · (1 + M) · 2E−bias

• Vorzeichen Bit V

• Mantisse M hat immer die Form 1.abc , also wird erste Stelleweggelassen (

”hidden bit“)

• Exponent E wird vorzeichenlos abgespeichert, verschoben umbias

• bei 32 bit float: bias = 127, bei 64 bit float: bias = 1023

15

3

Wiederholung letzte Vorlesung

Ganze Zahlen in C, C++

Ganze Zahlen in C, C++

• 8 Bits: unsigned char {0, . . . , 255}signed char {−128, . . . , 127}

• 16 Bits: unsigned short {0, . . . , 65535}signed short {−32768, . . . , 32767}

• 32 Bits: unsigned long {0, . . . , 232 − 1}signed long {−232, . . . , 232 − 1}

• 64 Bits: unsigned long long {0, . . . , 264 − 1}signed long long {−264, . . . , 264 − 1}

• signed kann weggelassen werden (ausser bei char!)

• unsigned int und signed int sind je nach System 16, 32oder 64 Bit

11

Floating Point Zahlen II

V Exponent E Mantisse M

23 Bit8 Bit 32 Bit float

64 Bit double52 Bit11 Bit

1 Bit

1 Bit

• wissenschaftliche Darstellung mit Basis 2

f = (−1)V · (1 + M) · 2E−bias

• Vorzeichen Bit V

• Mantisse M hat immer die Form 1.abc , also wird erste Stelleweggelassen (

”hidden bit“)

• Exponent E wird vorzeichenlos abgespeichert, verschoben umbias

• bei 32 bit float: bias = 127, bei 64 bit float: bias = 1023

15

Logische Werte und Verknupfungen

”Grundrechenarten“ mit logischen Werten:

• Konjunktion: ∧ : B × B → B• ahnlich zu Multiplikation bei Zahlen• auch bezeichnet als UND bzw. AND

• Disjunktion: ∨ : B × B → B• ahnlich zu Addition bei Zahlen• auch bezeichnet als ODER bzw. OR

• Negation: ¬ : B → B• auch bezeichnet als NICHT bzw. NOT

Wahrheitstabelle:

a b a ∧ b0 0 00 1 01 0 01 1 1

a b a ∨ b0 0 00 1 11 0 11 1 1

a ¬a0 11 0

21

3

Wiederholung letzte Vorlesung

Ganze Zahlen in C, C++

Ganze Zahlen in C, C++

• 8 Bits: unsigned char {0, . . . , 255}signed char {−128, . . . , 127}

• 16 Bits: unsigned short {0, . . . , 65535}signed short {−32768, . . . , 32767}

• 32 Bits: unsigned long {0, . . . , 232 − 1}signed long {−232, . . . , 232 − 1}

• 64 Bits: unsigned long long {0, . . . , 264 − 1}signed long long {−264, . . . , 264 − 1}

• signed kann weggelassen werden (ausser bei char!)

• unsigned int und signed int sind je nach System 16, 32oder 64 Bit

11

Floating Point Zahlen II

V Exponent E Mantisse M

23 Bit8 Bit 32 Bit float

64 Bit double52 Bit11 Bit

1 Bit

1 Bit

• wissenschaftliche Darstellung mit Basis 2

f = (−1)V · (1 + M) · 2E−bias

• Vorzeichen Bit V

• Mantisse M hat immer die Form 1.abc , also wird erste Stelleweggelassen (

”hidden bit“)

• Exponent E wird vorzeichenlos abgespeichert, verschoben umbias

• bei 32 bit float: bias = 127, bei 64 bit float: bias = 1023

15

Logische Werte und Verknupfungen

”Grundrechenarten“ mit logischen Werten:

• Konjunktion: ∧ : B × B → B• ahnlich zu Multiplikation bei Zahlen• auch bezeichnet als UND bzw. AND

• Disjunktion: ∨ : B × B → B• ahnlich zu Addition bei Zahlen• auch bezeichnet als ODER bzw. OR

• Negation: ¬ : B → B• auch bezeichnet als NICHT bzw. NOT

Wahrheitstabelle:

a b a ∧ b0 0 00 1 01 0 01 1 1

a b a ∨ b0 0 00 1 11 0 11 1 1

a ¬a0 11 0

21

Logische Ausdrucke in C, C++

• logische Variablen: bool a,b;

• logische Werte: true und false

• NOT Operator: !a

• AND Operator: a && b

• OR Operator: a || b

Beispiele:

• ( (2 == 2) && (3 > 1) )

ergibt (true && false), also false

• ( !(2 == 2) || (3 < 1) )

ergibt (false || true), also true

• Kurzform fur !(2 == 2) ist (2 != 2)

27

3

Programm heute

1 Einfuhrung

2 Mathematische GrundlagenMengenAbbildungenZahldarstellungBoolesche Logik

3 Elementare DatenstrukturenZeichenfolgenFelder

4

Definition Datenstruktur

Definition Datenstruktur (nach Prof. Eckert)

Eine Datenstruktur ist eine

• logische Anordnung von Datenobjekten,

• die Informationen reprasentieren,

• den Zugriff auf die reprasentierte Information uberOperationen auf Daten ermoglichen und

• die Information verwalten.

Zwei Hauptbestandteile:

• Datenobjekte• z.B. definiert uber primitive Datentypen

• Operationen auf den Objekten• z.B. definiert als Funktionen

5

Primitive Datentypen in C, C++

• Naturliche Zahlen, z.B. unsigned short, unsigned long

• Wertebereich: bei n Bit von 0 bis 2n − 1• Operationen: +, -, *, /, %, <, ==, !=, >

• Ganze Zahlen, z.B. int, long• Wertebereich: bei n Bit von −2n−1 bis 2n−1 − 1• Operationen: +, -, *, /, %, <, ==, !=, >

• Floating Point Zahlen, z.B. double, float• Wertebereich: abhangig von Große• Operationen: +, -, *, /, <, ==, !=, >

• Logische Werte, bool

• Wertebereich: true, false• Operationen: &&, ||, !, ==, !=

Was ist mit Zeichen und Zeichenfolgen?

6

Bits und Bytes

1 Byte = 8 Bit

Bit 0Bit 7

Bytes als Maßeinheit fur Speichergrossen:

• 210 Bytes = 1024 Bytes = 1 kB, ein kilo Byte (großes B)

• 220 Bytes = 1 MB, ein Mega Byte

• 230 Bytes = 1 GB, ein Giga Byte

• 240 Bytes = 1 TB, ein Tera Byte

• 250 Bytes = 1 PB, ein Peta Byte

• 260 Bytes = 1 EB, ein Exa Byte

Hinweis: auch Bits werden als Maßangabe verwendet, z.B. 16 Mbitoder 16 Mb (kleines b).

7

Bits und Bytes

1 Byte = 8 Bit

Bit 0Bit 7

Bytes als Maßeinheit fur Speichergrossen:

• 210 Bytes = 1024 Bytes = 1 kB, ein kilo Byte (großes B)

• 220 Bytes = 1 MB, ein Mega Byte

• 230 Bytes = 1 GB, ein Giga Byte

• 240 Bytes = 1 TB, ein Tera Byte

• 250 Bytes = 1 PB, ein Peta Byte

• 260 Bytes = 1 EB, ein Exa Byte

Hinweis: auch Bits werden als Maßangabe verwendet, z.B. 16 Mbitoder 16 Mb (kleines b).

7

Bytes und ASCII

Interpretation eines Bytes als Zeichen (anstatt Zahlen)−→ z.B. ASCII Code

7 Bit ASCII Code:

Code ..0 ..1 ..2 ..3 ..4 ..5 ..6 ..7 ..8 ..9 ..A ..B ..C ..D ..E ..F

0.. nul soh stx etx eot enq ack bel bs ht lf vt ff cr so si

1.. dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us

2.. sp ! “ # $ % & ’ ( ) * + , - . /

3.. 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

4.. @ A B C D E F G H I J K L M N O

5.. P Q R S T U V W X Y Z [ \ ] ˆ

6.. ‘ a b c d e f g h i j k l m n o

7.. p q r s t u v w x y z { ! } ˜ del

8

ASCII Erweiterungen, Unicode

• ASCII verwendet nur 7 Bit von einem Byte• enthalt z.B. keine Umlaute (a, o, u) oder Akzente (e, c)

• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)• belegt die Codes von 128-255 (bzw. 80-FF in hex)

• Unicode wurde als 16 Bit Codierung eingefuhrt• erste 128 Zeichen stimmen mit ASCII uberein• die nachsten 128 Zeichen mit ISO Latin-1• danach z.B. kyrillische, arabische, japanische Schriftzeichen

• UTF-8 ist eine Mehrbyte-Codierung von Unicode (1-6 Bytes)• Code-Lange wird durch die ersten Bits codiert

9

ASCII Erweiterungen, Unicode

• ASCII verwendet nur 7 Bit von einem Byte• enthalt z.B. keine Umlaute (a, o, u) oder Akzente (e, c)

• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)• belegt die Codes von 128-255 (bzw. 80-FF in hex)

• Unicode wurde als 16 Bit Codierung eingefuhrt• erste 128 Zeichen stimmen mit ASCII uberein• die nachsten 128 Zeichen mit ISO Latin-1• danach z.B. kyrillische, arabische, japanische Schriftzeichen

• UTF-8 ist eine Mehrbyte-Codierung von Unicode (1-6 Bytes)• Code-Lange wird durch die ersten Bits codiert

9

ASCII Erweiterungen, Unicode

• ASCII verwendet nur 7 Bit von einem Byte• enthalt z.B. keine Umlaute (a, o, u) oder Akzente (e, c)

• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)• belegt die Codes von 128-255 (bzw. 80-FF in hex)

• Unicode wurde als 16 Bit Codierung eingefuhrt• erste 128 Zeichen stimmen mit ASCII uberein• die nachsten 128 Zeichen mit ISO Latin-1• danach z.B. kyrillische, arabische, japanische Schriftzeichen

• UTF-8 ist eine Mehrbyte-Codierung von Unicode (1-6 Bytes)• Code-Lange wird durch die ersten Bits codiert

9

ASCII Erweiterungen, Unicode

• ASCII verwendet nur 7 Bit von einem Byte• enthalt z.B. keine Umlaute (a, o, u) oder Akzente (e, c)

• es gibt verschiedene Erweiterungen von ASCII auf 8 Bit• in Europa ist ISO Latin-1 verbreitet (ISO Norm 8859-1)• belegt die Codes von 128-255 (bzw. 80-FF in hex)

• Unicode wurde als 16 Bit Codierung eingefuhrt• erste 128 Zeichen stimmen mit ASCII uberein• die nachsten 128 Zeichen mit ISO Latin-1• danach z.B. kyrillische, arabische, japanische Schriftzeichen

• UTF-8 ist eine Mehrbyte-Codierung von Unicode (1-6 Bytes)• Code-Lange wird durch die ersten Bits codiert

9

Zeichen und Strings

Reprasentation eines ASCII Zeichens in C, C++: char

• Zeichen-Literale in einfachen Anfuhrungszeichen

Beispiele: ’A’, ’u’, ’D’

char zeichen = ’A’;

• Vorsicht bei nicht-ASCII Zeichen!

Reprasentation einer Zeichenfolge? (Englisch: String)

• String-Literale in doppelten Anfuhrungszeichen

Beispiel: “AuD“

• in C gespeichert als Folge von Zeichen, terminiert durch ’\0’

10

Zeichen und Strings

Reprasentation eines ASCII Zeichens in C, C++: char

• Zeichen-Literale in einfachen Anfuhrungszeichen

Beispiele: ’A’, ’u’, ’D’

char zeichen = ’A’;

• Vorsicht bei nicht-ASCII Zeichen!

Reprasentation einer Zeichenfolge? (Englisch: String)

• String-Literale in doppelten Anfuhrungszeichen

Beispiel: “AuD“

• in C gespeichert als Folge von Zeichen, terminiert durch ’\0’

'A' 'u' 'D' '\0'

10

Strings in C

Strings in C:

• dargestellt als Array von chars fester Lange:

char test_string [8];

• C Arrays werden indiziert von 0! (hier also von 0 bis 7)• immer genug Platz fur terminierendes ’\0’ einplanen!

• dargestellt als Array von chars dynamischer Lange (mittelsPointer):

char *test_string;

• Speicher muss explizit uber malloc/freeangefordert/freigegeben werden!

• Große des Arrays komplett in eigener Verantwortung!• sehr fehleranfallig, bitte vermeiden wenn moglich!

11

Strings in C

Strings in C:

• dargestellt als Array von chars fester Lange:

char test_string [8];

• C Arrays werden indiziert von 0! (hier also von 0 bis 7)• immer genug Platz fur terminierendes ’\0’ einplanen!

• dargestellt als Array von chars dynamischer Lange (mittelsPointer):

char *test_string;

• Speicher muss explizit uber malloc/freeangefordert/freigegeben werden!

• Große des Arrays komplett in eigener Verantwortung!• sehr fehleranfallig, bitte vermeiden wenn moglich!

11

Programm: Strings in C

#include <stdio.h>

#include <string.h>

int main()

{

char test_string [5] = "test"; // Laenge ist 4+1

printf("test_string:!%s\n", test_string );

char AuD_string [4];

AuD_string [0] = ’A’;

AuD_string [1] = ’u’;

AuD_string [2] = ’D’;

AuD_string [3] = ’\0’; // terminierende 0

printf("AuD_string:!%s\n", AuD_string );

printf("Laenge:!%lu\n", strlen(AuD_string) );

return 0;

}

12

Strings in C - Operationen

Operationen auf C Strings: definiert in string.h

• strlen(str): liefert Lange des Strings str

• strcpy(ziel, quelle): kopiert String quelle nach ziel

• ziel wird als groß genug vorausgesetzt!

• strcat(ziel, quelle): hangt String quelle an Stringziel hinten an

• ziel wird als groß genug vorausgesetzt!

• strcmp(str1, str2): vergleicht die Strings str1 und str2

• ist das Ergebnis 0, sind die Strings gleich

13

Programm: Strings in C (Fortsetzung)

#include <stdio.h>

#include <string.h>

int main()

{

char test_string [] = "test";

char AuD_string [] = "AuD";

char resultat_string [20]; // gross genug

strcpy(resultat_string , AuD_string );

printf("strcpy!Ergebnis:!%s\n", resultat_string );

int vergleich = strcmp(resultat_string , AuD_string );

printf("strcmp!Ergebnis:!%d\n", vergleich );

strcat(resultat_string , test_string );

printf("strcat!Ergebnis:!%s\n", resultat_string );

return 0;

}

14

Strings in C - Probleme

Probleme mit C Strings:

• terminierende ’\0’ wird vergessen

• Zuweisung nach Initialisierung schwierig

• Großenvoraussetzungen werden nicht automatisch gepruft

• Verwaltung von Strings dynamischer Lange eine Quelle derhaufigsten Programmierfehler

• aber gerade Strings dynamischer Lange werden gebraucht!

15

Strings in C++

Strings in C++:

• dargestellt als std::string

std:: string test_string;

• Zugriff wie bei C Strings uber [] Operator, indiziert von 0

std:: string test_string = "test";

test_string [1] = ’a’;

• automatische Verwaltung der Große

• nicht terminiert mit ’\0’, sondern speichert Große direkt

• Operationen direkt in std::string eingebaut

16

Programm: Strings in C++

#include <iostream >

#include <string >

using namespace std;

int main()

{

string test_string = "test";

cout << "test_string:!" << test_string << endl;

string AuD_string = "BvE";

AuD_string [0] = ’A’;

AuD_string [1] = ’u’;

AuD_string [2] = ’D’;

cout << "AuD_string:!" << AuD_string << endl;

cout << "Laenge:!" << AuD_string.length () << endl;

...

17

Programm: Strings in C++ (Fortsetzung)

...

string resultat_string;

resultat_string = AuD_string;

cout << "Kopieren:!" << resultat_string << endl;

bool vergleich = (resultat_string == AuD_string );

cout << "Vergleich:!" << vergleich << endl;

resultat_string = resultat_string + test_string;

// oder kuerzer:

// resultat_string += test_string;

cout << "Anhaengen:!" << resultat_string << endl;

return 0;

}

18

Programm heute

1 Einfuhrung

2 Mathematische GrundlagenMengenAbbildungenZahldarstellungBoolesche Logik

3 Elementare DatenstrukturenZeichenfolgenFelder

19

Definition Feld

Definition Feld

Ein Feld A ist eine Folge von n Datenelementen (di )i=1,...,n,

A = d1, d2, . . . , dn

mit n ∈ N0.

Die Datenelemente di sind beliebige Datentypen (z.B. primitive).

Beispiele:

• A sind die naturlichen Zahlen von 1 bis 10, aufsteigendgeordnet:

A = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

• Ist n = 0, so ist das Feld leer.

20

Feld als sequentielle Liste

Reprasentation von Feld A als sequentielle Liste (oder Array)

• feste Anzahl n von Datenelementen

• zusammenhangend gespeichert

• in linearer Reihenfolge mit Index

• Zugriff auf i-tes Element uber Index i: A[i]

...Feld A: A[n] A[n-1] A[2] A[1] A[0]

21

Beispiel sequentielle Liste

Feld A=0,8,15, Lange 3

• Beispiel in C:

int A[3];

A[0] = 0; A[1] = 8; A[2] = 15;

• Beispiel in C++:

std::vector <int > A(3);

A[0] = 0; A[1] = 8; A[2] = 15;

22

Eigenschaften sequentielle Liste

Feld A mit Lange n als sequentielle Liste (Array)

• Vorteile:• direkter Zugriff auf Elemente in konstanter Zeit mittels A[i]• sequentielles Durchlaufen sehr einfach

• Nachteile:• Verschwendung von Speicher falls Liste nicht voll belegt• Verlangern der sequentiellen Liste sehr aufwendig• Hinzufugen und Loschen von Elementen sehr aufwendig

23

C Beispiel: sequentielles Durchlaufen

Code:

int feldA [5];

int i;

// sequentielles Durchlaufen

printf("feldA:!");

for (i = 0; i < 5; ++i) {

feldA[i] = i * i;

printf("%d!", feldA[i]);

}

printf("\n");

Ausgabe:

feldA: 0 1 4 9 16

24

Verlangern der sequentiellen Liste

Gegeben: Feld A, Lange n, als sequentielle Liste

Gewunscht: Feld A erweitert auf Lange n+1

• neuen Speicher der Große n+1 reservieren

• alte Liste in neuen Speicher kopieren

...Feld A: A[n] A[n-1] A[2] A[1] A[0]

...neuesFeld A: A[n] A[n-1] A[2] A[1]A[n+1] A[0]

25

C Beispiel: Verlangern der Liste

Code:

int neuesFeldA [6];

// altes Feld kopieren:

for (i = 0; i < 5; ++i)

neuesFeldA[i] = feldA[i];

// neues Element:

neuesFeldA [5] = 25;

// neuesFeldA ausgeben:

printf("neuesFeldA!nach!Verlaengern:!");

for (i = 0; i < 6; ++i)

printf("%d!", neuesFeldA[i]);

printf("\n");

Ausgabe:

neuesFeldA nach Verlaengern: 0 1 4 9 16 25

26

Loschen von Element aus Liste

Gegeben: Feld A, Lange n, als sequentielle Liste

Gewunscht: Element i aus Feld A loschen

• Element i entfernen

• Listenelemente nach i umkopieren

25 16 4 1 09

- 25 9 4 116

27

C Beispiel: Loschen von Element

Code:

// loesche erstes Element

for (i = 1; i < 6; ++i)

neuesFeldA[i-1] = neuesFeldA[i];

// setze letztes Element auf -1

neuesFeldA [5] = -1;

// neuesFeldA ausgeben:

printf("neuesFeldA!nach!Loeschen:!");

for (i = 0; i < 6; ++i)

printf("%d!", neuesFeldA[i]);

printf("\n");

Ausgabe:

neuesFeldA nach Loeschen: 1 4 9 16 25 -1

28

Einfugen von Element in Liste

Gegeben: Feld A, Lange n, als sequentielle Liste

Gewunscht: neues Element in Feld A an Stelle i einfugen

• Listenelemente nach i umkopieren

• Element i einfugen

- 25 9 4 116

25 16 8 4 19

29

C Beispiel: Einfugen von Element

Code:

// neues Element (8) an 3. Stelle einfuegen

for (i = 5; i > 2; --i)

neuesFeldA[i] = neuesFeldA[i-1];

neuesFeldA [2] = 8;

// neuesFeldA ausgeben:

printf("neuesFeldA!nach!Einfuegen:!");

for (i = 0; i < 6; ++i)

printf("%d!", neuesFeldA[i]);

printf("\n");

Ausgabe:

neuesFeldA nach Einfuegen: 1 4 8 9 16 25

30

C++ Beispiel: sequentielle Listen

Code:

vector <int > feldA (5);

// sequentielles Durchlaufen

for (int i = 0; i < 5; ++i) {

feldA[i] = i * i;

}

// Verlaengern der Liste

feldA.resize (6);

feldA [5] = 25;

// loesche erstes Element

feldA.erase( feldA.begin() );

feldA [5] = -1;

// neues Element (8) an 3. Stelle einfuegen

feldA.insert( feldA.begin() + 2, 8);

31

Ausblick: Anwendung von sequentiellen Listen

in 2D und 3D Bildern!

32

Zusammenfassung

1 Einfuhrung

2 Mathematische GrundlagenMengenAbbildungenZahldarstellungBoolesche Logik

3 Elementare DatenstrukturenZeichenfolgenFelder

33