EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio...
-
Upload
liutpold-ebling -
Category
Documents
-
view
107 -
download
3
Transcript of EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 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 7
Claudio Moraga, Gisbert Dittrich
FBI Unido
2
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Gliederung Kapitel 7Gliederung Kapitel 7
• Verkettete Liste Version 1– Einhängen am Kopf
• Verkettete Liste Version 1a– Einlesen rekursiv
• Verkettete Liste Version 2– Einhängen am Fuß
• Verkettete Liste Version 3– Mit Entfernen
3
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete ListenVerkettete Listen
• Problem: – Möchte ganze Zahlen einlesen (Ende == 0); weiß
nicht, wie viele Zahlen eingegeben werden.
Mit Feldern? Problem.
Lösung: z.B. Verkettete Liste
4
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete ListenVerkettete Listen
struct Liste { int Element; Liste *weiter;};
Eine Variable vom Typ Liste enthält
also wieder einenZeiger auf ein
Datum vom Typ Liste•Also: auch in Typdeklaration Verwendung
von Rekursion möglich!
5
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete ListenVerkettete Listen
Element
Inhalt vom Typint
weiter
nächstes Element: Zeiger vom Typ Liste
6
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete Liste Version 1Verkettete Liste Version 1
Eine Variable, vereinbart als Liste *x, kann also z. B. auf so etwas zeigen:
7
9
hier ist dieListe zu Ende,
der Zeiger zeigt"auf Null"
3x
7
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete Liste Version 1 Verkettete Liste Version 1
• Der Zeiger, der eine Liste beendet, heißt NULL– NULL ist in C++ vordefiniert.
8
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete Liste Version 1Verkettete Liste Version 1
Liste *Einlesen ();void Ausdrucken (Liste *); main () { Liste *Ls; Ls = Einlesen (); Ausdrucken (Ls); }
Einlesen ist eine (parameterlose) Funktion, die einen Zeiger auf eine Liste zurückgibt (Ausdrucken hat einen Zeiger auf eine Liste als Parameter).
9
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
setze die Wertein dem neuen
Element
Die Funktion Die Funktion EinlesenEinlesen
Liste * Einlesen () { Liste *K, *Kopf = NULL; int i; cout << "Erstes Element? "; cin >> i; while (i != 0) { K = new Liste; K->Element = i; K->weiter = Kopf; Kopf = K; cout << "naechstes Element? “; cin >> i; } return Kopf;}
initialisiere Kopf zuNULL
erzeuge neues
Listenexemplar
10
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Die Funktion Die Funktion EinlesenEinlesen
new Liste erzeugt ein neues Exemplar von Liste und gibt einen Zeiger darauf zurück.
11
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
EinlesenEinlesen
Beim Eintritt in die Funktion
Kopf = NULL; Kopf
nach K = new Liste;
K
keineVerbindungzwischenbeiden
12
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
EinlesenEinlesen
Kopf
K
Nach Einlesen von i = 1; K->Element = i;
1
nachK->weiter = Kopf;
nach Kopf = K;
13
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
K
Kopf
1
nach K = new Liste;
2
Einlesen
K->Element = 2;
14
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
EinlesenEinlesen
Kopf
K 1
K 2
nach Kopf = K;
nachK->weiter = Kopf;
15
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Die Funktion Die Funktion AusdruckenAusdrucken
Die Funktion Ausdrucken ist rekursiv (d. h. ruft sich selbst auf)
void Ausdrucken (Liste *K) { if (K != NULL) { cout << K->Element << '\t' Ausdrucken (K->weiter); } else // jetzt ist K == NULL cout << "\n Das wars\n";}
16
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Ausdrucken + ProgrammAusdrucken + Programm
• Parameter K – weist auf nichts mehr (d.h. NULL): das war´s;
Beendigung des Aufrufs,– nicht-leere Restliste: Ausdruck des Elements,
erneuter Aufruf für die restliche Liste
(d. h. die bei K->weiter beginnende Liste)
– Programm:
Verkettete Liste 1
17
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
// K7-P1: Verkettete_Liste 1// demonstriert verkettete Listen und Rekursion
#include <iostream.h>
struct Liste {int Element;Liste *weiter;
};
Liste * Einlesen();void Ausdrucken(Liste *);
main() {Liste *Ls;Ls = Einlesen();Ausdrucken(Ls);
}; 1
18
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Liste * Einlesen() {Liste *K, *Kopf = NULL;int i;cout << "Erstes Element? ";cin >> i; // Vorsicht: nur Zahlen eingeben !!!!
while (i != 0) {K = new Liste;K->Element = i;K->weiter = Kopf;Kopf = K;cout << "naechstes Element? ";cin >> i;
}return Kopf;
}2
19
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
void Ausdrucken(Liste *K) {
if (K != NULL) {cout << K->Element << '\t';Ausdrucken(K->weiter);}
else // jetzt ist K == NULL
cout << "\n\n\t Das wars, Leute! \n";}
3
Ausführen
20
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Einlesen (rekursiv)Einlesen (rekursiv)
Liste *Einlesen () {
Liste *K; int i;
cout << "Zahl? "; cin >> i;
K = new Liste;K->Element = i;K->weiter =
(i != 0 ? Einlesen (): NULL); return K;
} hier stecktdie
Abbruchbedingung
es wird ein neuesExemplar erzeugt
(mit new)
21
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Einlesen (rekursiv)Einlesen (rekursiv)
K->weiter =(i != 0 ? Einlesen (): NULL);
Kritische Stelle • i != 0: der Zeiger K->weiter wird auf dasjenige Element gesetzt, das sich durch erneutes Einlesen ergibt,•i == 0: der Zeiger wird auf NULL gesetzt, kein weiterer Aufruf.
22
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete Liste: Einfügen am EndeVerkettete Liste: Einfügen am Ende
Idee: Zeiger auf das letzte Element.
FußKopf
23
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Initialisierung des Codes ein wenig trickreich
Programm:
Verkettete Liste: Einfügen am EndeVerkettete Liste: Einfügen am Ende
Verkettete Liste 2
24
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
// K7-P2: Verkettete Liste 2// demonstriert verkettete Listen und // Rekursion// (Einfügen am "Fuß")//
#include <iostream.h>
struct Liste {int Element;Liste *weiter;
};1
25
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
main() {Liste * Einlesen(), *Ls;void Ausdrucken(Liste *);
Ls = Einlesen();Ausdrucken(Ls);
}
2
26
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Liste * Einlesen() {Liste *Kopf = NULL, *Fuss = NULL; int i;cout << "Zahl? "; cin >> i;while (i != 0) {
Liste *K = new Liste;K->Element = i; K->weiter = NULL;if (Kopf == Fuss){//noch nichts eingefuegt
Kopf = K; Kopf->weiter = Fuss;}else if (Fuss == NULL){
Kopf->weiter = K; Fuss = K;}else {
Fuss->weiter = K; Fuss = K;}cout << "Zahl? "; cin >> i;
} return Kopf;
} 3
27
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
void Ausdrucken(Liste *K) {if (K != NULL) {
cout << K->Element << '\t';Ausdrucken(K->weiter);}
else // jetzt ist K == NULL cout << "\n\n\t Das wars, Leute\n";}
4
Ausführen
28
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Verkettete Liste incl. EntfernenVerkettete Liste incl. Entfernen
Gegeben: Liste * L, ganze Zahl i• Liste ist leer: gib L zurück• L->Element == i:
gib Liste L->weiter zurück• L->Element != i:
– entferne i aus der Liste L->weiter – gib L zurück
29
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Beispiel: Entfernen von 3Beispiel: Entfernen von 3
11
44
33
22
30
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Entfernen aus einer ListeEntfernen aus einer Liste
Liste *Entferne (int i, Liste *L) { if (L == NULL)
return L; else if (L ->Element == i)
return L->weiter; else {
L->weiter = Entferne (i, L->weiter);return L;
}}
Fall 1
Fall 2Fall 3
Verkettete Liste 3
31
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
// K7-P3: Verkettete Liste 3// demonstriert verkettete Listen// und Rekursion// (mit Entfernen eines Listenelementes)//
#include <iostream.h>#include <stdio.h>
struct Liste {int Element;Liste *weiter;
};
1
32
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Liste * Einlesen();Liste * Entferne(int i, Liste * );void Ausdrucken(Liste *);int GanzeZahlLesen(char *);void GanzeZahlSchreiben(char *, int);main() {
Liste *Ls; int ent; Ls = Einlesen();cout << "\neingelesene Liste: " << endl;Ausdrucken(Ls);ent = GanzeZahlLesen("\n\nEntfernen? ");while ((ent != -1) && (Ls != NULL)) {
// -1 Abbruchkriterium aus EntfernenGanzeZahlSchreiben
("\nListe nach Entfernen von: ", ent);Ls = Entferne(ent, Ls);
Ausdrucken(Ls);ent = GanzeZahlLesen("\n\nEntfernen? ");}
cout << "\n\n\tCiao“ << endl;} 2
33
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
int GanzeZahlLesen(char * prompt) {
int i;cout << prompt;cout << "(ganze Zahl bzw. Abbruch mit -1)\t";cin >> i;return i;
} void GanzeZahlSchreiben(char * prompt, int Zahl) { cout << prompt << Zahl << endl; }
3
34
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Liste * Einlesen() {Liste *K, *Kopf = NULL;int i;cout << "Erstes Element? ";cin >> i;
while (i != 0) {K = new Liste;K->Element = i;K->weiter = Kopf;Kopf = K;cout << "naechstes Element? ";cin >> i;
}return Kopf;
}
4
35
Kap 7: Verkettete Listen Vorl “EINI-I"
18.12.2000
Liste * Entferne(int i, Liste * L) {if (L == NULL)
return L;else if (L->Element == i)
return L->weiter;else {
L->weiter = Entferne(i, L->weiter);return L;}
}
void Ausdrucken(Liste * MeineListe){ while (MeineListe != NULL){
cout << MeineListe->Element << ", "; MeineListe = MeineListe->weiter;
} }
5
Ausführen