EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 9 Claudio...

Post on 05-Apr-2015

110 views 0 download

Transcript of EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 9 Claudio...

EINI-IEINI-IEinführung in die Informatik Einführung in die Informatik für Naturwissenschaftler und für Naturwissenschaftler und

Ingenieure IIngenieure I

Kapitel 9

Claudio Moraga; Gisbert Dittrich

FBI Unido

moraga@cs.uni-dortmund.de

2

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Gliederung Kapitel 9Gliederung Kapitel 9

• Einfache Dateibehandlung• Beispiel: Wörter zählen

– Problem, Datenstruktur – Einfügen: Strategie + Implementierung– Alphabetisch geordnete Ausgabe: Strategie + Impl.

• Durchlaufstrategien bei Bäumen– In die Tiefe

• Inorder • Präorder • Postorder

– In die Breite

3

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

DateienDateien

• Einfache Dateibehandlung – (externe Dateien, Öffnen, Lesen/Schreiben,

Schließen).– Am Beispiel: Problem, die Wörter in einem

gegebenen Text zu zählen und sie mit ihrer Häufigkeit alphabetisch geordnet auszugeben.

• Zunächst: Dateien • Lies aus einer Eingabe-Datei, schreibe in eine

Ausgabe-Datei. Am elementaren Beispiel.• Programm

4

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

DateienDateien

• #include <fstream.h>

bindet die Bibliothek zur Dateibehandlung ein

• Bindung von Datei-Variablen (im Programm) an Dateien (im Dateisystem) beim Öffnen der Datei.

ifstream *Eingabedatei; EingabeDatei = new ifstream(EinDat);

• Benutzung von Dateien: wie Standard Ein-/Ausgabe

– ifstream: Eingabe - ofstream: Ausgabe

• Benutzung: wie cin (bzw. cout)– *Eingabedatei >> gelesen;

5

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

DateienDateien

• Testen: (*Eingabedatei).eof() (liefert "true" genau dann, wenn das Ende der Datei

erreicht ist; eof: end of file)!(*Eingabedatei).eof() (liefert "true" genau dann, wenn das Ende der Datei

noch nicht erreicht ist)

• Analog: ofstream *AusgabeDatei;

• Werden Dateien zum Schreiben geöffnet, so geht meist ihr vorheriger Inhalt verloren.

6

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

// K9-P1// Elementare Verwendung von Dateien// Vorsicht: nicht robust

#include <iostream.h>#include <fstream.h>

const int maxLen = 70;

void Einlesen(ifstream *, ofstream *);void Schreiben(char * , ofstream *);

1

7

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

main() {ifstream *EingabeDatei;ofstream *AusgabeDatei;char EinDat[80], AusDat[80];cout << "bitte Eingabedatei angeben: "; cin >> EinDat;cout << "bitte AusgabeDatei angeben: "; cin >> AusDat;cout << "Danke" << endl;EingabeDatei = new ifstream(EinDat);AusgabeDatei = new ofstream(AusDat);Einlesen(EingabeDatei, AusgabeDatei);

cout << "fertig" << endl;}

2

8

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

void Einlesen(ifstream *ein, ofstream *aus) {char gelesen[maxLen];*ein >> gelesen;while (!(*ein).eof()) {

cout << "gelesen: " << gelesen << "\t\t\t\t";

Schreiben (gelesen, aus);*ein >> gelesen;

}}void Schreiben(char *Wort, ofstream *aus) {

if (Wort != NULL) {

*aus << Wort << endl; // Wort mit ..... //..Zeilenumbruch in die Datei schreiben.cout << "geschrieben: " << Wort << endl;

// Wort mit Zeilenumbruch ... //..auf den Bildschirm schreiben.

}} // 3Ausführen

9

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Wörter zählenWörter zählen

• Problem: – zähle die Wörter in einem gegebenen Text, – gib sie mit ihrer Häufigkeit alphabetisch geordnet

aus.

• Datenstruktur: – binärer Suchbaum (--> Wörter lassen sich ordnen)– erweitert um einen Zähler.

10

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Datenstruktur zum Zählen von WörternDatenstruktur zum Zählen von Wörtern

text

zaehler

LSohn RSohn

struct BinBaum {char text[maxLen];int zaehler;BinBaum * LSohn, *RSohn;

};

11

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Strategie zum EinfügenStrategie zum Einfügen

• Suchen nach einer Zeichenkette im binären Suchbaum– Zeichenkette nicht gefunden:

• neuen Knoten einfügen,

• Zähler zu 1 initialisieren

– Zeichenkette gefunden: • Zähler um 1 erhöhen

12

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

void strcpy(char *, char *);int strcmp(char *, char *);

BinBaum * Einfuegen(BinBaum *B, char * k) {if (B == NULL) {

BinBaum *Hilf = new BinBaum;strcpy(Hilf->text, k);Hilf->zaehler = 1;

Hilf->LSohn = Hilf->RSohn = NULL;B = Hilf; Hilf = NULL;}

else {int Vergl = strcmp(B->text,k);if (Vergl < 0)

B->RSohn = Einfuegen(B->RSohn, k);else if (Vergl > 0)

B->LSohn = Einfuegen(B->LSohn, k);else if (Vergl == 0)

B->zaehler += 1;}

return B;}

Text noch nicht

gesehen

Text bekannt:einfügen,

Zählererhöhen

13

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Alphabetisch geordnete AusgabeAlphabetisch geordnete Ausgabe

• Behauptung:• Nachfolgender Durchlauf liefert als Resultat:

– geordnete Ausgabe

• Durchlaufstrategie:– Durchlaufe den binären Suchbaum mit Wurzel w

rekursiv wie folgt:• Durchlauf durch den linken Unterbaum von w

• Ausdruck (der Nutzinfo) der Wurzel w

• Durchlauf durch den rechten Unterbaum von w

14

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Beispiel (Baumdurchlauf)Beispiel (Baumdurchlauf)

4 7

6

17

18

23

26

4 6 7 17 18 23 26

4 7

17

18

23

26

6

15

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

BeweisBeweis

• Durch vollständige Induktion nach der Anzahl der Knoten– Der Induktionsbeginn (kein Knoten) ist erfüllt– Der Induktionsschritt:

• der linke Unterbaum wird geordnet ausgegeben (IV),

• dann wird die Wurzel ausgegeben,

• dann wird der rechte Unterbaum geordnet ausgegeben (IV).

(Die Wurzel steht bzgl. der Ordnung "in der Mitte".)

16

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Programmtext: Programmtext: AusdruckenAusdrucken

void KnotenDruck(BinBaum *, ofstream *); void Ausdrucken(BinBaum *K, ofstream *aus) {

if (K != NULL) {Ausdrucken(K->LSohn, aus);KnotenDruck(K, aus);Ausdrucken(K->RSohn, aus);}

}

Programm

17

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

AnmerkungenAnmerkungen

• Zugriff auf Ein- und Ausgabedateien wird über Zeiger auf ifstream- und ofstream-Variablen bewirkt.

• Initialisierungen– EingabeDatei = new ifstream(EinDat);– AusgabeDatei = new ofstream(AusDat);

• Varianten (Ausgabedateien als Konstante bekannt) z.B.: – ofstream *Ausgabe = new ofstream("von.aus");

18

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

BinBaum * Einfuegen(BinBaum *, char *);BinBaum * Einlesen(ifstream *ein) {

BinBaum *bst = NULL;char gelesen[maxLen];

*ein >> gelesen;while (!(*ein).eof()) {

bst = Einfuegen(bst, gelesen);*ein >> gelesen;

}return bst;

}

Feinheiten: *ein und (*ein).eof()

19

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Analog: AusgabeAnalog: Ausgabe

void Schreiben(char *, int, ofstream *);void KnotenDruck(BinBaum *T, ofstream *aus){

Schreiben(T->text, T->zaehler, aus);}void Schreiben(char * s, int k, ofstream *aus){

*aus << k << "\t\t\t" << s << endl;}

20

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

// K9-P2 Binärer Suchbaum//#include <iostream.h>#include <fstream.h>#include <string.h> // beinhaltet void strcpy(char *, char *); // und int strcmp(char *, char *);

const int maxLen = 70;

struct BinBaum {

char text[maxLen];int zaehler;BinBaum * LSohn, *RSohn;

};// 1

Bibliothek für die DateibehandlungBibliothek für die Dateibehandlung

21

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

// Funktionsprototypen

BinBaum * Einlesen(ifstream *);BinBaum * Einfuegen(BinBaum *, char *);void Ausdrucken(BinBaum *, ofstream *);void KnotenDruck(BinBaum *, ofstream *);void Schreiben(char * , int , ofstream *);

// 2

22

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

main() {BinBaum *BST;ifstream *EingabeDatei;ofstream *AusgabeDatei;char EinDat[80], AusDat[80];

cout << "bitte Eingabedatei angeben: "; cin >> EinDat;cout << "bitte AusgabeDatei angeben: "; cin >> AusDat;cout << "Danke" << endl;EingabeDatei = new ifstream(EinDat);AusgabeDatei = new ofstream(AusDat);

BST = Einlesen(EingabeDatei);Ausdrucken(BST, AusgabeDatei);

cout << "fertig" << endl;} // 3

23

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

BinBaum * Einlesen(ifstream *ein) {

BinBaum *bst = NULL; char gelesen[maxLen];

*ein >> gelesen;while (!(*ein).eof()) {

bst = Einfuegen(bst, gelesen);*ein >> gelesen;

};return bst;

}

// 4

24

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

BinBaum * Einfuegen(BinBaum *B, char * k) {if (B == NULL) {

BinBaum *Hilf = new BinBaum;strcpy(Hilf->text, k);Hilf->zaehler = 1;

Hilf->LSohn = Hilf->RSohn = NULL;B = Hilf; Hilf = NULL;}

else {int Vergl = strcmp(B->text,k);if (Vergl < 0) B->RSohn = Einfuegen(B->RSohn, k);else if (Vergl > 0) B->LSohn = Einfuegen(B->LSohn, k);else if (Vergl == 0) B->zaehler += 1;}

return B;}// 5

25

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

void Ausdrucken(BinBaum *K, ofstream *aus) {if (K != NULL) {

Ausdrucken(K->LSohn, aus);KnotenDruck(K, aus);Ausdrucken(K->RSohn, aus);}

}

void KnotenDruck(BinBaum *T, ofstream *aus){Schreiben(T->text, T->zaehler, aus);

}

void Schreiben(char * s, int k, ofstream *aus){*aus << k << "\t\t\t" << s << endl;

} // 6

26

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Durchlauf durch BäumeDurchlauf durch Bäume

4 7

6

17

18

23

26

Diese Art des Durchlaufs heißt Inorder-Durchlauf.

w

BLinks BRechtsInorder ( )

Inorder(Wurzel BLinks)

Druck(w)

Inorder(Wurzel BRechts)

=

4 6 7 17 18 23 26

27

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

w

BLinks BRechtsPräorder( ) Präorder(Wurzel BLinks)

Druck(w)

Präorder(Wurzel BRechts)

=

17 6 4 7 23 18 2617

6

4 7

23

18 26

28

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

w

BLinks BRechts

Postorder( )Postorder(Wurzel BLinks)

Druck(w)

Postorder(Wurzel BRechts)=

4 7

6

18 26

23

174 7 6 18 26 23 17

29

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

DurchlaufstrategienDurchlaufstrategien

• Strategie bei allen drei Durchlaufarten heißt Tiefensuche:

Es wird zunächst in die Tiefe und nicht in die Breite gegangen.

• Alternative: Breitensuche Trage den Baum "schichtenweise" ab.

30

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Beispiel BreitensucheBeispiel Breitensuche

6 23

4 7 18 26

17

17 6 23 4 7 18 26

31

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

Idee zur ImplementationIdee zur Implementation

Verwalte die Knoten in einer "Warteschlange"

• ein Knoten wird gedruckt

• seine Söhne werden in die Warteschlange eingefügt

bis die Warteschlange leer ist

Initialisierung der Warteschlange mit der Wurzel des Baums.

32

Kap 9: Durchlaufstrategien Vorl “EINI-I"

09.01.2001

BeispielBeispiel

17 6 23 4 7 18 26

17

6 23

4 7 18 26