问题概述:古代有一个梵塔,塔内有3个座A,B,C。开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上,有一个老和尚想把64个盘子从A座移动到C座,但是规定每次只允许移动一个盘,且在移动过程中在3个座上都始终保持大盘在下,小盘在上。在移动的过程中可以利用B座。(写出移动的步骤)。
问题分析:在这个问题中,我们先来看如果盘子总量n=3时的情况,因为最终要将盘子移动到C中,所以最终情况一定是最大的第3个盘子在C上,然后再将前两个在B上的盘子移动到C上,如何将前两个盘子移动到B上呢?就是要将此时最大的第二个盘子移动到B上,然后将第一个盘子从A移动到B上,实现了两层函数的递归。总结:问题分为三步:1,将最大的盘子前面的n-1个移动到B上,将最大的盘子移动到C上,然后将B上的n-1个移动到C上。这三步中的第一步操作步骤为:将n-2个盘子移动到C上,将最大的盘子移动到B上,然后将第n-2个盘子移动到B上,第三步的操作步骤为:将n-2个盘子移动到A上,将第n-2个盘子移动到C上,再将前面n-2个盘子移动到C上。这三步中第一步操作步骤为:将n-3个盘子移动到B上,将最大的盘子移动到C上,然后将第n-3个盘子移动到C上,以此类推。在步骤中涉及参数的改变和函数的递归问题。以4个盘子为例做出流程图如下:
问题代码:
#include
void Hanoi( int n, char a, char b, char c);//汉诺塔函数声明
void Move( int n, char a, char b);//输出操作步骤函数的函数声明
int count;
int main()
{
int n=8;
printf ( "汉诺塔的层数:\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);//因为最终要将所有盘子移动到C上,所以将B,C进行形式互换//
Move(n, a, c);
Hanoi(n - 1, b, a, c);//和第一步同理//
}
}
void Move( char a, char b)
{
count++;
printf ( "第%d次移动 Move: Move from %c to %c !\n" ,count,a,b);
}