Hanoi(汉诺)塔问题

问题:
古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上,有一个老和尚想把这64个盘子从A座移到C座,但规定每次只允许移动一个盘,且再移动的过程中在3个座上都始终保持大盘在下,小盘在上,在移动过程中可以利用B座,要求编写程序输出移动盘子的步骤。

分析:
要将n个盘子从A移到C,只需要将n-1个盘子从A移到B(视为一个整体,不需要考虑具体的移动方法),然后将第n个盘子从A移到C,然后将B上的n-1个盘子从B再移到C上就可以;
那么如何将n-1个盘子由A移到B呢,采用相似的方法,只需要将n-2个盘子从A移到C,然后将第n-1个盘子从A移到B,然后将C上的n-2个盘子移到B,放在第n-1个盘子上面即可。
那么如何将n-2个盘子从A移到C呢,采用相似的方法……
直到最后剩下一个问题:如何将最顶上的1个盘子从A移到C(或者B)

由此可见,这是一个递归问题,不断被重复的步骤为“将xx个盘子从A移到B或者C”,终止条件为最后只剩下最顶上一个盘子的移动问题

解决方法:
用函数void Hanoi(n,A,B,C)代表借助B将n个盘子从A移到C的操作,用Move函数表示将一个盘子从某个柱子移到另一个柱子
void Hanoi(n,int A,int B,int C)
{
if(n==1)
move(A,C);
else
{Hanoi(n-1,A,C,B);
Move(A,C);
Hanoi(n-1,B,A,C);}
}

完整程序:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

int main()
{
void hanoi(int n,char A,char B,char C);
int n;
printf(“please input the number of plate:\n”);
scanf(“%d”,&n);
hanoi(n,’A’,’B’,’C’);
return 0;
}

void hanoi(int n,char A,char B,char C)
{
if(n==1)
move(A,C);
else
{hanoi(n-1,A,C,B);
move(A,C);
hanoi(n-1,B,A,C);}
}

void move(char x,char y)
{
printf(“move %c to %c\n”,x,y);
}

程序的具体执行过程分析
n=3
main主函数调用hanoi函数,将实参‘A’赋给形参A,实参‘B’赋给形参B,实参‘C’赋给形参C,实参n=3赋给形参n
1)hanoi(3,A,B,C)(A=‘A’,B=‘B’,C=‘C’)函数调用hanoi(2,A,B,C),将表达式n-1取值2赋给形参n,A取值‘A’赋给形参A,C取值‘C’赋给形参B,B取值‘B’赋给形参C;
调用函数move(x,y),将A取值‘A’赋值给x,C取值‘C’赋值给y,打印“A–>C”;
调用函数hanoi(n,A,B,C)将n-1=2赋值给形参n,B取值‘B’赋值给形参A,A取值‘A’赋值给形参B,C取值‘C’赋值给形参C;

1.1)hanoi(2,A,B,C)(A=‘A’,B=‘C’,C=‘B’)函数
调用hanoi(1,A,B,C),将表达式n-1取值1赋给形参n,A取值‘A’赋给形参A,C取值‘B’赋给形参B,将B取值’C’赋给形参C;
调用函数move(x,y),将A取值‘A’赋给形参x,C取值‘B’赋给形参y,打印“A–>B”;
调用函数hanoi(1,A,B,C)将n-1=1赋给形参n,B取值‘C’赋给形参A,A取值‘A’赋给形参B,C取值‘B’赋给形参C;
1.2)打印“A–>C”
1.3)hanoi(2,A,B,C)(A=‘B’,B=’A’,C=’C’)
调用函数hanoi(1,A,B,C)将表达式n-1=1赋给形参n,A取值‘B’赋给形参A,C取值‘C’赋给形参B,B取值‘A’赋给形参C;
调用函数move(x,y),将A取值‘B’赋给形参x,C取值‘C’赋给形参y,打印B–>C;
调用函数hanoi(1,A,B,C)将表达式n-1=1赋给形参n,B取值‘A’赋给形参A,A取值‘B’赋给形参B,C取值‘C’赋给形参C;

1.1.1)hanoi(1,A,B,C)(A=’A’,B=’B’,C=’C’)调用move函数,打印
A–>C

1.1.2)打印
A–>B;
1.1.3)hanoi(1,A,B,C)(A=’C’,B=’A’,C=’B’)调用move函数,打印
C–>B;
1.2)打印
A–>C
1.3.1)hanoi(1,A,B,C)(A=’B’,B=C”,C=’A’)调用Move函数,打印
B–>A;
1.3.2)打印
B–>C;
1.3.3)hanoi(1,A,B,C)(A=’A’,B=’B’,C=’C’)调用Move函数,打印
A–>C;

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/LAI_Beiqi/article/details/80618587
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞