Grundgebiete der Informatik 2 Algorithmen und Programmiertechniken Tutorium

Grundgebiete der Informatik 2: Algorithmen und Programmiertechniken Tutorium zur Klausurvorbereitung RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 1

EBNF • • Gibt mögliche Programmstruktur vor Darstellungsform für kontextfreie Grammatiken Äquivalent zu Syntaxdiagrammen Sequenz, Option [ ], Wiederholung { }, Alternative |, Rekursion number ident factor ( expression ! factor ) Rekursion factor : : = number | ident | ( expression ) | ! factor Nichtterminal. Symbol RWTH Aachen – Lehrstuhl für Informatik 3 Metasymbole der EBNF Terminal. Symbol Grundlagen der Informatik: Algorithmen und Programmiertechniken 2

Ableiten eines Worts aus einer EBNF • Wort: Folge von Terminalsymbolen, die durch Anwendung von Regeln einer Grammatik/EBNF erzeugt wurde • Beispiel bezieht sich auf EBNF aus Aufgabe 1 if ( a + b == !c) { cout << "test"; } 1 if ( expression ) { statement. List } 2 6 if ( simple. Expression relation simple. Expression ) { statement } 4 3 4 8 if ( factor add. Operator factor == factor) { cout << string; } 5 7 5 5 if (ident + ident == RWTH Aachen – Lehrstuhl für Informatik 3 ! factor ) { cout << string; } 5 ! ident) { cout << string; } Grundlagen der Informatik: Algorithmen und Programmiertechniken 3

Ebenen der Syntax & Semantik • Lexikalische Syntax: Schlüsselwörter, Bezeichner, Literale, Begrenzer, . . . EBNF • Kontextfreie Syntax (Aufbausyntax): Beschreibt Aufbau eines Programms Ausdrücke, Anweisungen, Deklarationen, Programmstruktur • Kontextsensitive Syntax: Beschreibt Beziehungen zwischen Teilen eines Programms • Semantik: Beschreibt die Bedeutung der Elemente, aus denen ein Programm aufgebaut ist RWTH Aachen – Lehrstuhl für Informatik 3 Umgangssprachlich Grundlagen der Informatik: Algorithmen und Programmiertechniken 4

Beispiel für Ebenen der Syntax #include <iostream. h> int summiere(int a, int b) { return a + b ; } int main() { int a, b, summe ; cin >> a >> b; summe = summiere(a, b); cout << summe << endl; } Lexikalische Syntax • Literale: 1. 8 e 6 ; ``Hallo`` • Schlüsselworte: int, return • Bezeichner: summiere, a, b • Begrenzer: ; { } ( ) space tab • Kommentare: Eine lexikalische Einheit, die aber ignoriert wird Kontextfreie Syntax Ausdrücke Deklarationen Anweisungen Programmstruktur Kontextsensitive Syntax Zur Deklaration RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 5

Alte Klausuraufgabe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include "iostream" using namespace std; void Straight. Insertion(char ffeld[], int start, int ende) { int j; char elem for (int i=start+1; i<=ende, i++) { // aktuelles Element merken elem=ffeld[k]; /* an der richtigen Stelle in den bereits sortierten Anfang Einfuegen */ j=i; while ((j>start) & (elem<ffeld[j-1]) { ffeld[j] = ffeld[j-1]; j--; } ffeld[j] = elem; } } RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 6
![Alte Klausuraufgabe 4 void Straight. Insertion(char ffeld[], int start, int ende){ … 21 22 Alte Klausuraufgabe 4 void Straight. Insertion(char ffeld[], int start, int ende){ … 21 22](http://slidetodoc.com/presentation_image/0f3de590251a5c3324a4cd72b2b3dc61/image-7.jpg)
Alte Klausuraufgabe 4 void Straight. Insertion(char ffeld[], int start, int ende){ … 21 22 23 24 25 26 27 28 29 30 31 … } int main() { char feld[] ={ 'v', k, 'a', 'h', 'j', 'l', 'e', 'b'}; Straight. Insertion(*feld, 0, 7); for (int i=0; i<8; i++) { cout << feld[i] << ' '; } return 0; } RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 7

Kontrollstrukturen • Fallunterscheidungen if ( zahl > 0 ) { // Anweisungsfolge } Einseitig bedingte Anweisung if ( zahl > 0 ) { // Anweisungsfolge } else { // Alternative A. } Zweiseitig bedingte Anweisung RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 8

Kontrollstrukturen • Auswahlanweisung enum Wochentag { Mo, Di, Mi, Do, Fr, Sa, So }; Wochentag Tag; switch ( Tag ) { case Mo: // Anweisungen break; case Di: case Mi: // Anweisungen break; default: // Anweisungen break; } RWTH Aachen – Lehrstuhl für Informatik 3 Fall „Mo“ Fälle ‚ „Di“ und „Mi“ Alle anderen Fälle (optional) Grundlagen der Informatik: Algorithmen und Programmiertechniken 9

Kontrollstrukturen • Schleifen – Wiederholte Ausführung einer Anweisungsfolge (Block) – Unterscheidung • Anzahl der Iterationen bekannt for-Schleife // Berechnung der Fakultät int eingabe, fakultaet = 1; cin >> eingabe; for ( int i=1; i < eingabe; i++ ) { fakultaet *= i; } • Anzahl der Iterationen unbekannt while-Schleife // Reaktion auf Messfuehler while ( Messfuehler. Gib. Wert() > 0 ) { cout << "Aktueller Wert: " << Messfuehler. Gib. Wert() << endl; } cout << "Wert ist nicht mehr positiv!" << endl; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 10

Prozedur vs. Funktion vs. Methode • Prozedur – – Führt eine Anweisungsfolge aus Basiert auf Parametern, verändert diese gegebenenfalls Kein Rückgabewert Beenden der Prozedur durch return; (optional) void Ausgabe( int a ) { cout << a << endl; } • Funktion – Wie Prozedur, aber: – Hat Rückgabewert ungleich void – Beenden der Funktion & Rückgabe durch return-Anweisung int Eingabe() { int eingabe; cin >> eingabe; } // Auf Groß-/Kleinschreibung achten! return eingabe; • Methode – Gehört zu einer Klasse (bspw. ADT) "member function" – Kann Prozedur oder Funktion sein – Durch Klassenzugehörigkeit: Zugriff auf private Klassen-Elemente RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 11

Variablen, Pointer, Referenzen Prinzipiell • Pointer var. Typ var. Bezeichner; – Deklaration: Vor jedem Var. -Bezeichner * • Referenzen – Deklaration: Vor jedem Var. -Bezeichner – Muss direkt initialisiert werden & • Dereferenzierung: * "Folgt dem Zeiger" • Adresse von: & "Liefert Zeiger auf" int a; int *pa; int &ra = a; // Integer-Variable, Name: "a" // Pointer/Zeiger auf Integer-Variable // Referenz auf Integer-Variable pa = &a; // Pointer "pa" zeigt nun auf "a" a = 10; cout << a; *pa = 20; cout << a; ra = 30; cout << a; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 12

Parameterübergabe: Beispiel Call by Reference Call by Value #include "iostream. h" void f(int &x, int y, int *z) { y++; x=*z+y; x++; ++(*z); } a b c vor 1. Aufruf 1 2 3 nach 1. Aufruf 7 2 4 nach 2. Aufruf 8 2 5 int main() { int a=1, b=2, c=3; f(a, b, &c); //1. Aufruf cout << "1. Aufruf: " << a << b << char(13) << char(10); f(a, b, &c); //2. Aufruf cout << "2. Aufruf: " << a << b << char(13) << char(10); return 0; } RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 13
![Datentypen: vordefinierte, Typdeklaration Objektdeklaration • Vordefinierte Typen (Beispiele): [unsigned] int, char, [unsigned] double, short, Datentypen: vordefinierte, Typdeklaration Objektdeklaration • Vordefinierte Typen (Beispiele): [unsigned] int, char, [unsigned] double, short,](http://slidetodoc.com/presentation_image/0f3de590251a5c3324a4cd72b2b3dc61/image-14.jpg)
Datentypen: vordefinierte, Typdeklaration Objektdeklaration • Vordefinierte Typen (Beispiele): [unsigned] int, char, [unsigned] double, short, float, . . . double dbl; • Arrays: int i[41]; int *i[41]; Objektdeklarationen • Typdeklaration: typedef int *p. Int. T; • Verwendung: p. Int. T pi; RWTH Aachen – Lehrstuhl für Informatik 3 Objektdeklaration Grundlagen der Informatik: Algorithmen und Programmiertechniken 14
![Datentypen: Arrays, Strukturen, . . . • Aufzählungstypen [typedef] enum Werktag {di, mi}; • Datentypen: Arrays, Strukturen, . . . • Aufzählungstypen [typedef] enum Werktag {di, mi}; •](http://slidetodoc.com/presentation_image/0f3de590251a5c3324a4cd72b2b3dc61/image-15.jpg)
Datentypen: Arrays, Strukturen, . . . • Aufzählungstypen [typedef] enum Werktag {di, mi}; • Arrays typedef int* Int. Ptr. Feld[41]; Typdeklaration • Strukturen [typedef] struct My. Struct { int i; My. Struct* next; }; • Verwendung My. Struct a. Struct; Int. Ptr. Feld an. Array; RWTH Aachen – Lehrstuhl für Informatik 3 Objektdeklarationen Grundlagen der Informatik: Algorithmen und Programmiertechniken 15

Datentypen: komplexes Beispiel struct My. Struct { int i; Some. Type* info; }; typedef My. Struct Complex. Array[7]; Complex. Array an. Array; 1 27 3 8 5 22 53 RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 16

Speicherallokation und Freigabe • Speicher auf dem Heap allokieren: i. Ptr int* i. Ptr; i. Ptr=new int; *i. Ptr=42; . . . • Allokierten Speicher wieder freigeben: delete i. Ptr; i. Ptr=NULL; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 17

Datentypen: Zugriff auf Strukturkomponenten struct My. Struct { int i; My. Struct* next; }; My. Struct s; My. Struct *ps; ps=&s; s. i=9; (*ps). i=9; ps->i=9; RWTH Aachen – Lehrstuhl für Informatik 3 s->i=9; //falsch ps. i=9; //falsch Grundlagen der Informatik: Algorithmen und Programmiertechniken 18

Datenstrukturen: Verkettete Liste struct l. Elem. T{ int value; l. Elem. T *next; }; Laufzeiger head l. Elem. T* head; . . . head=NULL; 3 9 77 z. B. Element einfügen new. Elem z head 122 37 // z: Einfuegestelle l. Elem. T *new. Elem=new l. Elem. T; new. Elem->value=37; 3 9 77 122 new. Elem->next=z->next; z->next=new. Elem; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 19

Graphrealisierungen 2 1 1 3 2 • • 3 knotenorientiert – Adjazenzlisten = Liste von Knoten, jeder Knoten hat Liste 1 2 seiner Nachfolger 3 • sequentiell • verkettet – charakteristische Adjazenzmatrix = Matrix, Knoten in Zeilenund Spaltenüberschriften, Kantengewichte bzw. 1/0 in Zellen kantenorientiert 1 2 3 – Kantenlisten 1 1 2 • sequentiell 2 3 3 • verkettet – charakteristische Inzidenzmatrix = Knoten in Zeilenüberschriften, Kanten in Spaltenüberschriften RWTH Aachen – Lehrstuhl für Informatik 3 2 3 3 1 2 3 1 2 1 -1 -1 2 1 3 3 -1 1 1 Grundlagen der Informatik: Algorithmen und Programmiertechniken 20

Sortierenalgorithmen RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 21

Aufwandsabschätzung in O-Notation • O-Notation – Gibt Größenordnung an – Abstrahiert von "unwichtigen" Details/Faktoren – Oft Abschätzung für besten, mittleren und schlechtesten Fall z. B. : • Quadratischer Aufwand: • Logarithmischer Aufwand: a·log(n)+c • Linearer Aufwand • Konstanter Aufwand RWTH Aachen – Lehrstuhl für Informatik 3 O(log(n)) Grundlagen der Informatik: Algorithmen und Programmiertechniken 22

Sortierverfahren (1) Sortieren durch Einfügen (Straight Insertion) Bester Fall: O(n) Mittlerer Fall: O(n²) Schlechtester Fall: O(n²) sortiert Bubblesort "Größte Blase steigt auf" RWTH Aachen – Lehrstuhl für Informatik 3 Bester Fall: O(n) Mittlerer Fall: O(n²) Schlechtester Fall: O(n²) sortiert Grundlagen der Informatik: Algorithmen und Programmiertechniken 23

Sortierverfahren (2) Quicksort a <a Bester Fall: O(n log 2 n) Mittlerer Fall: O(n log 2 n) Schlechtester Fall: O(n²) a Rekursion! RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 24

Suchverfahren • Lineare Suche: – Laufe von vorne nach hinten bis Element gefunden Bester Fall: O(1) Mittlerer Fall: O(n) Schlechtester Fall: O(n) • Binäre Suche: – Sortierung vorausgesetzt ! – vergleiche mittlerem Element: • gleich: gefunden • kleiner: wiederhole Suche in linker Hälfte • größer: wiederhole Suche in rechter Hälfte Bester Fall: O(1) Mittlerer Fall: O(log 2 n) Schlechtester Fall: O(log 2 n) – wenn Hälfte leer: nicht gefunden RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 25

Module RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 26

Getrennte Übersetzung ausführbares Programm #include "a. h" a. cpp/cc Compile a. obj a. h Link a. h *. cpp/cc RWTH Aachen – Lehrstuhl für Informatik 3 Compile *. obj Grundlagen der Informatik: Algorithmen und Programmiertechniken 27

Module Zugriff Schnittstelle Modul Rumpf • Datenabstraktion – abstrahiert von Realisierung der Datenstruktur • Funktionale Abstraktion – abstrahiert vom Algorithmus • Ziele: • Änderungen im Rumpf ohne Auswirkungen auf Verwender, Wartbarkeit • Zergliederung in Teile • Arbeitsteilung • Modul-Test • Entwurf vor Realisierung, Softwarearchitektur RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 28

Modularten • ADO : Abstraktes Daten-Objekt – Datenabstraktion – Exakt ein Objekt zur Laufzeit – Alle Operationen auf diesem Objekt – Allokation/Erzeugung und De-Allokation/Zerstörung durch Laufzeitsystem DA • ADT : Abstrakter Daten-Typ – Datenabstraktion – Schablone, beliebig viele Instanzen zur Laufzeit erzeugbar – Instanz bei jeder Operation angeben – Allokation/Erzeugung und Deallokation/Zerstörung in Verantwortung des Programmierers • FM : FA Funktionales Modul – Funktionale Abstraktion – Transformierendes Modul Funktionsbibliothek – Kein "Gedächtnis" Keine Seiteneffekte RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 29

Realisierung der Modularten (ADO, FM) bool Element. Einfuegen(int Element); Header. Datei (. h) ADO bool Element. Loeschen(int Element); . . . Schnittstelle Rumpf Implementierungs. Datei (. cc/. cpp) static Bin. Baum baum; //Datenspeicher bool Element. Einfuegen(int wert) {. . . }. . . FM: ohne Datenspeicher, sonst gleiche Realisierung RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 30

Realisierung der Modularten (ADT) class Bin. Baum { public: Ref. Knoten Erzeuge. Neuen. Knoten(int wert). . . private: ADT Int. Knoten* wurzel; Schnittstelle Rumpf . . . }; Header-Datei (. h) struct Bin. Baum: : Int. Knoten {. . . } Bin. Baum: : Ref. Knoten Bin. Baum: : Erzeuge. Neuen. Knoten(int wert) {. . . } Implementierungs. Datei (. cc/. cpp) RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 31

Funktionales Modul (FM) - Umsetzung //trig. h Header-Datei=Schnittstelle double sinus(double x); double tan(double x); double cos(double x); . . . #include "trig. h" double sinus(double x) {. . . } . cpp/. cc-Datei=Rumpf double tan(double x) {. . . double cos(double x) {. . . } RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 32

Beispiel: ADT-Bin. Baum • ADT-Bin. Baum: – Realisierung eines ADT Bin. Baum – Jeder Knoten hat Zeiger auf Vater – Beispiel für Entwicklung einer Datenstruktur • Beispiel für Verwendung des ADT – main • ADO Menge erstellen: – Realisierung mit Hilfe des ADT Bin. Baum – Menge nutzt Bin. Baum zur Speicherung • ADO-Bin. Baum: – selber Bin. Baum, jetzt als ADO • Beispiel für Verwendung des ADO – main RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 33

Definieren von Datenstrukturen Ziel: Binärer Baum mit Zeiger auf Vater Idee: 3 3 RWTH Aachen – Lehrstuhl für Informatik 3 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 34

Definieren von Datenstrukturen Konkreteres Modell: 3 3 RWTH Aachen – Lehrstuhl für Informatik 3 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 35

Definieren von Datenstrukturen Umsetzung in Programmiersprache C++: struct Bin. Baum: : Int. Knoten { Int. Knoten* vater; int inhalt; 3 Int. Knoten* linkes. Kind; Int. Knoten* rechtes. Kind; }; Int. Knoten* wurzel; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 36

ADT-Umsetzung: Header-Datei // Bin. Baum. h: Schnittstelle für den ADT Bin. Baum. class Bin. Baum { // Der außen verwendete opake Datentyp für Bäume private: struct Int. Knoten { int inhalt; Int. Knoten* vater; Int. Knoten* linkes. Kind; Int. Knoten* rechtes. Kind; }; "Geheime" Definition von Int. Knoten* m_Wurzel; public: typedef Int. Knoten* Ref. Knoten; Bin. Baum(); // Konstruktor Ref. Knoten zusätzlicher "opaker" Datentyp zur gezielten Identifikation einzelner Knoten Gib. Wurzel(); Gib. Linkes. Kind(Ref. Knoten vater); Gib. Rechtes. Kind(Ref. Knoten vater); Gib. Vater(Ref. Knoten aktueller. Knoten); Navigation Manipulation Ref. Knoten Erzeuge. Neuen. Knoten(int wert); void Setze. Wurzel( Ref. Knoten neue. Wurzel ); void Einhaengen. Knoten. Links( Ref. Knoten vater, Ref. Knoten neues. Kind ); void Einhaengen. Knoten. Rechts( Ref. Knoten vater, Ref. Knoten neues. Kind ); void Setze. Wert( Ref. Knoten zu. Aender. Knoten, int wert ); int Gib. Wert( Ref. Knoten zu. Lesender. Knoten ); . . . }; RWTH Aachen – Lehrstuhl für Informatik 3 Zugriff auf Inhalt Grundlagen der Informatik: Algorithmen und Programmiertechniken 37

ADT-Umsetzung: . cpp/. cc-Datei #include "Bin. Baum. h" Bin. Baum: : Ref. Knoten Bin. Baum: : Erzeuge. Neuen. Knoten(int wert) { Methode Int. Knoten *knoten = new Int. Knoten; gehört zur Klasse Bin. Baum knoten->inhalt = wert; knoten->vater = NULL; knoten->linkes. Kind = NULL; knoten->rechtes. Kind = NULL; Knoten erzeugen Initialisieren, vgl. Definition der Struktur return knoten; } Bin. Baum: : Ref. Knoten Bin. Baum: : Gib. Linkes. Kind(Ref. Knoten vater) { return vater->linkes. Kind; aussen } intern darf die Struktur zugegriffen werden RWTH Aachen – Lehrstuhl für Informatik 3 ist Struktur von vater nicht zugreifbar Grundlagen der Informatik: Algorithmen und Programmiertechniken 38

Beispiel: ADT-Bin. Baum • ADT-Bin. Baum: – Realisierung eines ADT Bin. Baum – Jeder Knoten hat Zeiger auf Vater – Beispiel für Entwicklung einer Datenstruktur • Beispiel für Verwendung des ADT – main • ADO Menge erstellen: – Realisierung mit Hilfe des ADT Bin. Baum – Menge nutzt Bin. Baum zur Speicherung • ADO-Bin. Baum: – selber Bin. Baum, jetzt als ADO • Beispiel für Verwendung des ADO – main RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 39

ADT-Umsetzung: Verwendung #include "Bin. Baum. h" Bin. Baum baum; Instanz des ADTs (der Klasse) Aufruf von Methoden der Instanz void main() { Bin. Baum: : Ref. Knoten kn=baum. Erzeuge. Neuen. Knoten(42); baum. Setze. Wurzel(kn); . . . kn=baum. Gib. Linkes. Kind(baum. Gib. Wurzel()); cout << baum. Gib. Wert(kn); } Anmerkung: ADT in der Klausur immer als Klasse in der Praxis (und auch in Vorlesung und Übung) auch anders RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 40

Beispiel: ADT-Bin. Baum • ADT-Bin. Baum: – Realisierung eines ADT Bin. Baum – Jeder Knoten hat Zeiger auf Vater – Beispiel für Entwicklung einer Datenstruktur • Beispiel für Verwendung des ADT – main • ADO Menge erstellen: – Realisierung mit Hilfe des ADT Bin. Baum – Menge nutzt Bin. Baum zur Speicherung – Nur Schnittstelle verwenden! • ADO-Bin. Baum: – selber Bin. Baum, jetzt als ADO • Beispiel für Verwendung des ADO – main RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 41

ADO-Umsetzung: Header Datei Bei ADO: nur öffentliche Schnittstelle = Header-Datei ADO //Menge. h //Realisierung einer Menge basierend auf einem Binärbaum //Fuegt das Element item in die Menge ein //Rueckgabewert: true, wenn erfolgreich // false, wenn item schon Element der Menge bool Element. Einfuegen(int Element); //Entfernt das Element item aus der Menge //Rueckgabewert: true, wenn erfolgreich // false, wenn item nicht Element der Menge bool Element. Loeschen(int Element); Menge ADT Bin. Baum //Testet, ob item in der Menge enthalten ist //Rueckgabewert: true, wenn ja // false, sonst bool ist. Element(int Element); //Testet, ob die Menge leer ist //Rueckgabewert: true, wenn ja false, sonst bool ist. Leer(); RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 42

ADO-Umsetzung: . cpp/. cc-Datei #include "Menge. h" #include "Bin. Baum. h" Bin. Baum baum; genau ein Datenobjekt vom Typ Bin. Baum bool Element. Einfuegen(int wert) { Bin. Baum: : Ref. Knoten knoten; Bin. Baum: : Ref. Knoten neuer. Knoten; Implementierung von Funktionen if (baum. Gib. Wurzel()==NULL) { //ist der Baum leer? neuer. Knoten=baum. Erzeuge. Neuen. Knoten(wert); baum. Setze. Wurzel(neuer. Knoten); return true; } else {. . . } return false; }. . . RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 43

Beispiel: ADT-Bin. Baum • ADT-Bin. Baum: – Realisierung eines ADT Bin. Baum – Jeder Knoten hat Zeiger auf Vater – Beispiel für Entwicklung einer Datenstruktur • Beispiel für Verwendung des ADT – main • ADO Menge erstellen: – Realisierung mit Hilfe des ADT Bin. Baum – Menge nutzt Bin. Baum zur Speicherung • ADO-Bin. Baum: – gleicher Bin. Baum wie oben, jetzt als ADO • Beispiel für Verwendung des ADO – main RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 44

ADO-Umsetzung (mit Typ): Header-Datei // Bin. Baum. h: Schnittstelle für den ADO Bin. Baum. struct Int. Knoten; typedef Int. Knoten* Ref. Knoten; Ref. Knoten Vorabdeklaration des Privaten Typs, Definition folgt im Rumpf Gib. Wurzel(); Gib. Linkes. Kind(Ref. Knoten vater); Gib. Rechtes. Kind(Ref. Knoten vater); Gib. Vater(Ref. Knoten aktueller. Knoten); Verwender kann diesen Typ zum gezielten Zugriff auf einzelne Knoten nutzen Ref. Knoten Erzeuge. Neuen. Knoten(int wert); void Setze. Wurzel( Ref. Knoten neue. Wurzel ); void Einhaengen. Knoten. Links( Ref. Knoten vater, Ref. Knoten neues. Kind ); void Einhaengen. Knoten. Rechts( Ref. Knoten vater, Ref. Knoten neues. Kind ); void Setze. Wert( Ref. Knoten zu. Aender. Knoten, int wert ); int Gib. Wert( Ref. Knoten zu. Lesender. Knoten ); . . . Methoden-Deklarationen Auch ein ADO kann einen Typ exportieren: • Die eigentliche Datenstruktur (der Baum) existiert nur ein mal => ADO. • Zusätzlich gibt es einen weiteren Typ zur Identifikation von Knoten. RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 45

ADO-Umsetzung(mit Typ): . cpp/. cc-Datei #include "Bin. Baum. h" struct Int. Knoten { int inhalt; Int. Knoten *vater, *linkes. Kind, *rechtes. Kind; Vollständige Definition des Typs }; Int. Knoten* m_Wurzel; Wurzel des Baumes, private Variable Ref. Knoten Erzeuge. Neuen. Knoten(int wert){ Int. Knoten *knoten = new Int. Knoten; knoten->inhalt = wert; knoten->vater = NULL; knoten->linkes. Kind = NULL; knoten->rechtes. Kind = NULL; return knoten; }. . . RWTH Aachen – Lehrstuhl für Informatik 3 Methoden. Implementierungen Grundlagen der Informatik: Algorithmen und Programmiertechniken 46

Beispiel: ADT-Bin. Baum • ADT-Bin. Baum: – Realisierung eines ADT Bin. Baum – Jeder Knoten hat Zeiger auf Vater – Beispiel für Entwicklung einer Datenstruktur • Beispiel für Verwendung des ADT – main • ADO Menge erstellen: – Realisierung mit Hilfe des ADT Bin. Baum – Menge nutzt Bin. Baum zur Speicherung • ADO-Bin. Baum: – selber Bin. Baum, jetzt als ADO • Beispiel für Verwendung des ADO – main RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 47

Generizität RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 48

Generizität Allgemein • Gewisse „Stellschrauben“ (generische Instanzparameter) in der Realisierung von einzelnen Funktionen oder auch ganzen ADTs offenlassen – Nützlich bei Kollektionen: Stellschrauben sind Eintragstyp und Größe template <class T, int size> class Buffer { public: void enqueue(T x); . . . private: T internes. Feld[size]. . . }; • „Stellschrauben“ werden vom Verwender je nach Bedarf „festgezogen“ (Erzeugung spezieller Typ-Instanzen) typedef Buffer<int, 100> Int. Buffer; typedef Buffer<Person*, 20> Person. Buffer; . . . Int. Buffer my. Int. Buffer; my. Int. Buffer. enqueue(42); my. Int. Buffer. enqueue(„Ich will rein!“); //Fehler Compile-Zeit • Nutzen: Vermeidung von Code-Redundanz (kein Extra-Buffer für jeden Eintragstyp und jede Größe zu implementieren) RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 49

ADT DLList: Schnittstelle (. h) class DLList { public: DLList(); void append(int item); void delete. Current(); void delete. Index(int index); void to. Start(); void to. End(); void next(); void prev(); int read(); . . . private: struct List. Item { int value; List. Item *next, *prev; }; List. Item *first; List. Item *last; List. Item *current; // Zeiger auf das erste Element der Liste // Zeiger auf das letzte Element der Liste // Zeiger auf das aktuelle Element }; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 50

ADT DLList: Rumpf (. cc). . . void DLList: : prev() { if (current == NULL) { cerr << "DLList: : prev: current == NULL" << endl; return; } if (current == first) { cerr << "DLList: : next: am Anfang der Liste" << endl; return; } current = current->prev; } int DLList: : read() { if (current == NULL) return -1; return current->value; }. . . RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 51

ADT Gen. DLList: Schnittstelle (. h) template<class Value_T> class Gen. DLList { public: Gen. DLList(); void append(Value_T item); void delete. Current(); void delete. Index(int index); void to. Start(); void to. End(); void next(); void prev(); Value_T read. Next(); . . . private: struct List. Item { Value_T value; List. Item *next, *prev; }; List. Item *first; List. Item *last; List. Item *current; // Zeiger auf das erste Element der Liste // Zeiger auf das letzte Element der Liste // Zeiger auf das aktuelle Element }; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 52

ADT Gen. DLList: Rumpf (. cc) #ifndef __INC_Gen. DLList_cc #define __INC_Gen. DLList_cc. . . template<class Value_T> void Gen. DLList<Value_T>: : prev() { if (current == NULL) { cerr << "Gen. DLList: : prev: current == NULL" << endl; return; } if (current == first) { cerr << "Gen. DLList: : next: am Anfang der Liste" << endl; return; } current = current->prev; } template<class Value_T> Value_T Gen. DLList<Value_T>: : read() { if (current == NULL) return NULL; return current->value; }. . . #endif RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 53

ADT Lec. Adm: Schnittstelle (. h) #include „Gen. DLList. cc“ class Lec. Adm { public: void Add. Lecture(std: : string lec. Name); void Remove. Lecture(std: : string lec. Name); . . . private: // 1. Deklaration der Typ-Instanz 'Int. List' typedef Gen. DLList<int> Int. List; // 2. Deklaration der Verbundtypen // 'Student' und 'Lecture' struct Student { int mat. Nr; std: : string name; }; struct Lecture { std: : string name; Int. List listeners; }; // 3. Deklaration der Typ-Instanzen 'Student. List' und 'Lecture. List' typedef Gen. DLList<Student*> Student. List; typedef Gen. DLList<Lecture*> Lecture. List; // 4. Deklaration der Listen (Datenobjekte) 'students' und 'lectures' Student. List students; Lecture. List lectures; }; RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 54

ADT Lec. Adm: Rumpf (. cc) #include „Lec. Adm. h“ void Lec. Adm: : Add. Lecture(string lec. Name) { Lecture* new. Lec = new Lecture; new. Lec->name = lec. Name; lectures. append(new. Lec); } bool Lec. Adm: : Add. Student. To. Lecture(int mat. Nr, string lec. Name) { lectures. to. Start(); while (!lectures. is. At. End() && lectures. read()->name != lec. Name) { lectures. next(); } if (lectures. read()->name == lec. Name) { lectures. read()->listeners. append(mat. Nr); return true; } else { return false; } }. . . RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 55

Objektorientierung RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 56

Objektorientierung: Klassen und Vererbung class Graphic. Object { private: . . . public: virtual void draw(. . . ); } Graphic. Object void draw(). . . Rectangle void draw() void set. UL() void set. LR(). . . class Rectangle: public Graphic. Object { private: . . . public: void draw(. . . ); void set. UL(int x, int y); void set. LR (int x, int y); } RWTH Aachen – Lehrstuhl für Informatik 3 Circle void draw() void set. Mid() void set. Rad(). . . class Circle: public Graphic. Object { private: . . . public: void draw(. . . ); void set. Mid(int x, int y); void set. Rad(int x, int y); } Grundlagen der Informatik: Algorithmen und Programmiertechniken 57

Objektorientierung: Dynamische Bindung Graphic. Object *go; Circle *c; Rectangle *r; Graphic. Object. List gl; r=new Rectangle(); r->set. UL(10, 10); r->set. LR(15, 25); gl. add(r); class Graphic. Object { private: . . . public: virtual void draw(. . . ); } speziellste Methode ausführen c=new Circle(); c->set. Mid(25, 30); c->set. Rad(10); Graphic. Object. List Graphic. Object* Rectangle gl. add(c); RWTH Aachen – Lehrstuhl für Informatik 3 Circle . . . gl. goto. First(); while (gl. has. Current()) { go=gl. get. Current(); go->draw(); gl. goto. Next(); } Grundlagen der Informatik: Algorithmen und Programmiertechniken 58

Objektorientierung: Vorsicht mit virtual! class A { public: void f(); virtual void g(); }; class B : public A { public void f(); void g(); }; void A: : f() { cout << "f } void A: : g() { cout << "g } void B: : f() { cout << "f } void B: : g() { cout << "g } void main() { A *a; B *b; b=new B(); b->f(); b->g(); a=b; a->f(); a->g(); von A"; } von A"; f und g von B kein virtual f von A virtual g von B Ausgabe: von B"; RWTH Aachen – Lehrstuhl für Informatik 3 f g von von B B A B Grundlagen der Informatik: Algorithmen und Programmiertechniken 59

ADO-Umsetzung: Verwendung Es muss keine Instanz angelegt werden, da genau eine Instanz existiert #include "Bin. Baum. h" void main() { Ref. Knoten kn=Erzeuge. Neuen. Knoten(42); Setze. Wurzel(kn); . . . kn=Gib. Linkes. Kind(Gib. Wurzel()); cout << Gib. Wert(kn); } Daher muss auch keine Instanz beim Zugriff angegeben werden Der Typ Ref. Knoten wird zum Zugriff auf einzelne Knoten genutzt RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 60

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 61

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 62

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 63

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 64

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 65

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 66

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 67

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 68

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 69

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 70

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 71

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 72

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 73

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 74

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 75

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 76

RWTH Aachen – Lehrstuhl für Informatik 3 Grundlagen der Informatik: Algorithmen und Programmiertechniken 77
- Slides: 77