Die Türme von Hanoi Timm Grams Fachhochschule Fulda Fachbereich Elektrotechnik und Informationstechnik © Timm Grams, Fulda, 21.11.02

Download Report

Transcript Die Türme von Hanoi Timm Grams Fachhochschule Fulda Fachbereich Elektrotechnik und Informationstechnik © Timm Grams, Fulda, 21.11.02

Die Türme von Hanoi
Timm Grams
Fachhochschule Fulda
Fachbereich Elektrotechnik und
Informationstechnik
© Timm Grams, Fulda, 21.11.02
Die Türme von Hanoi
- Das Problem
Gegeben seien drei Pflöcke, die wir mit A, B und C
bezeichnen. Zu Beginn stecken auf Pflock A genau
n Scheiben. Die Scheiben werden von unten nach
oben immer kleiner. Folgende Grundregel ist
während des ganzen Spiels einzuhalten: Scheiben
werden grundsätzlich auf Pflöcke gesteckt und nie
daneben gelegt, und außerdem darf nie eine
Scheibe auf einer kleineren liegen. Die Aufgabe
lautet, die Scheiben - unter Beachtung der Regel von Pflock A nach Pflock B zu transportieren.
Die Türme von Hanoi
A
B
C
Die Türme von Hanoi
- Programmidee
Die Aufgabe, n Scheiben vom Quellturm zum Zielturm zu
transportieren, führt man auf die wohl etwas einfachere
Aufgabe für n-1 Scheiben zurück.
Also: Man bringt die n-1 obersten Scheiben vom Ziel- auf
den Hilfsturm, dann legt man die unterste Scheibe auf den
Zielturm und anschließend werden die n-1 Scheiben vom
Hilfsturm auf den Zielturm transportiert.
Das Problem für n-1 Scheiben behandelt man nun genau
so. Man führt es zurück auf den Transport von n-2
Scheiben. Und so weiter. Bis man nur noch eine Scheibe
transportieren muss.
Die Türme von Hanoi
- Programm
/*A, B, C: Quell-, Ziel und Hilfsturm*/
void move(char A, char B, char C, int n){
if(n>1) move(A, C, B, n-1);
printf("%5d:%c ---> %c\n", n, A, B);
if (n>1) move(C, B, A, n-1);
}
void main(){
int n;
printf("DIE TUERME VON HANOI\n");
printf("? Anzahl Scheiben = ");
scanf("%d", &n);
move('A', 'B', 'C', n);
}
Zur Visualisierung des Ablaufs
Aufbau der folgenden Folien
Befehlszähler
(Program
Counter, PC)
Programmspeicher
(Ausschnitt)
Stapelspeicher (Stack)
Die Türme
Für jeden Funktionsaufruf wird ein Funktionssegment (Activation Record) angelegt.
Es wird als ein Blatt Papier visualisiert, das auf
die bereits daliegenden Papiere gelegt wird. Es
enthält die automatischen Variablen für die
Parameter und die Rücksprungadresse (RA).
Nach Beendigung der Funktion wird der
Befehlszähler auf den Wert der Rücksprungadresse (Return Address, RA) gesetzt und das
Segment wird vom Stack entfernt.
Ablauf
Befehlszähler
(Program
Counter, PC)
Die Türme
Programmspeicher
(Ausschnitt)
Nach Eingabe der Zahl 3 erfolgt im
Hauptprogramm der Funktionsaufruf
"move('A', 'B', 'C', 3);".
Das ergibt die folgende Situation.
(Das zuunterst liegende Funktionssegment für das
Hauptprogramm ist weggelassen worden. Der
weitere Fortgang ist dem Wert des Befehlszählers
zu entnehmen.)
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 1
C
A
A: 'A'
B
A: 'A' A: 'A' B: 'B'
B: 'B' B: 'C' C: 'C'
C: 'C' C: 'B' n: 1
n:
2
n: 3
RA: 2
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A
A: 'A'
B
A: 'A' A: 'A' B: 'B'
B: 'B' B: 'C' C: 'C'
C: 'C' C: 'B' n: 1
n:
2
n: 3
RA: 2
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A
A: 'A'
B
A: 'A' A: 'A' B: 'B'
B: 'B' B: 'C' C: 'C'
C: 'C' C: 'B' n: 1
n:
2
n: 3
RA: 2
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A
A: 'A'
B
A: 'A' A: 'A' B: 'B'
B: 'B' B: 'C' C: 'C'
C: 'C' C: 'B' n: 1
n:
2
n: 3
RA: 2
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A: 'A' A: 'A'
B: 'B' B: 'C'
C: 'C' C: 'B'
n:
2
n: 3
A
B
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A: 'A' A: 'A'
B: 'B' B: 'C'
C: 'C' C: 'B'
n:
2
n: 3
A
B
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 1
C
A
A: 'B'
B
A: 'A' A: 'A'
B: 'C'
B: 'B' B: 'C'
C: 'A'
C: 'C' C: 'B'
n: 1
n:
2
n: 3
RA: 4
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A
A: 'B'
B
A: 'A' A: 'A'
B: 'C'
B: 'B' B: 'C'
C: 'A'
C: 'C' C: 'B'
n: 1
n:
2
n: 3
RA: 4
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A
A: 'B'
B
A: 'A' A: 'A'
B: 'C'
B: 'B' B: 'C'
C: 'A'
C: 'C' C: 'B'
n: 1
n:
2
n: 3
RA: 4
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A
A: 'B'
B
A: 'A' A: 'A'
B: 'C'
B: 'B' B: 'C'
C: 'A'
C: 'C' C: 'B'
n: 1
n:
2
n: 3
RA: 4
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A: 'A' A: 'A'
B: 'B' B: 'C'
C: 'C' C: 'B'
n:
2
n: 3
A
B
RA: 2
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 1
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 1
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'C'
B: 'A'
C: 'B'
n: 1
RA: 2
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'C'
B: 'A'
C: 'B'
n: 1
RA: 2
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'C'
B: 'A'
C: 'B'
n: 1
RA: 2
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'C'
B: 'A'
C: 'B'
n: 1
RA: 2
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 1
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'A'
B: 'B'
C: 'C'
n: 1
RA: 4
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 2
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'A'
B: 'B'
C: 'C'
n: 1
RA: 4
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 3
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'A'
B: 'B'
C: 'C'
n: 1
RA: 4
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
A: 'A'
B: 'B'
C: 'C'
n: 1
RA: 4
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
A: 'C'
B: 'B'
C: 'A'
n: 2
RA: 4
RA: STOP
Ablauf
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
PC: 4
C
A: 'A'
B: 'B'
C: 'C'
n: 3
A
B
RA: STOP
Ablauf
PC: STOP
void move(char A, char B, char C, int n){
1: if(n>1) move(A, C, B, n-1);
2: printf("%5d:%c ---> %c\n", n, A, B);
3: if (n>1) move(C, B, A, n-1);
4:
}
C
Das war's
A
B
So sieht die Sache jetzt aus
A
B
C
Ende des Foliensatzes