一、题目描述:
现在有n个圆盘从上往下从小到大叠在第一根柱子上,要把这些圆盘全部移动到第三根柱子要怎么移动呢?请找出需要步骤数最少的方案因此我们可以将问题简化描述为:n个盘子和3根柱子:A(源)、B(目的)、C(备用),盘子的大小不同且中间有一孔,可以将盘子“串”在柱子上,每个盘子只能放在比它大的盘子上面。起初,所有盘子在A柱上,问题是将盘子一个一个地从A柱子移动到B柱子。移动过程中,可以使用C柱,但盘子也只能放在比它大的盘子上面。
二、算法思想:
汉诺塔问题是递归算法的典型代表,递归的本质是大而化小,利用的是计算机的堆栈来实现的。递归过程可以分为以下几步:
第一步:将n-1个盘子从A柱移动至B柱(借助C柱为过渡柱)
第二步:将A柱底下最大的盘子移动至B柱
第三步:将C柱的n-1个盘子移至B柱(借助A柱为过渡柱)
其中将n-1作为一个整体,假想进行操作,这里就利用的递归的思想,我们可以比作生活中的领导安排任务,领导将任务一层一层往下传递,领导都是不做具体的事,把落实放到最底层去,最底层然后一级一级往上汇报,最终完成领导的任务。
三、核心代码:
void Hanoi(int n,char a,char b,char c)
{
if(n==1)
Move(n,a,b);//递归的出口
else
{
Hanoi(n-1,a,c,b);//将n-1个盘由实参a移动到实参c(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
Move(n,a,b);//将最大盘由a移动到b(函数实际起操作的部分,将形参a移动到b)
Hanoi(n-1,c,b,a);//将n-1个盘由实参c移动到实参b(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
}
}
void Move(int n,char a,char b)
{
printf("Move %d: from %c to %c\n",n,a,b);
}
四、完整代码:
/*
汉诺塔问题
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define EPS 1e-6
void Hanoi(int n,char a,char b,char c);
void Move(int n,char a,char b);
main()
{
int n=0;
printf("please input the scale of Hanoi\n");
scanf("%d",&n);
Hanoi(n,'A','B','C');
}
void Hanoi(int n,char a,char b,char c)
{
if(n==1)//递归的出口
Move(n,a,b);
else
{
Hanoi(n-1,a,c,b);//将n-1个盘由实参a移动到实参c(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
Move(n,a,b);//将最大盘由a移动到b(函数实际起操作的部分,将形参a移动到b)
Hanoi(n-1,c,b,a);//将n-1个盘由实参c移动到实参b(由函数形参可以看出,每次移动的是a和b,也就是Hanoi(n,a,b,c)中的前两个a和b。)
}
}
void Move(int n,char a,char b)
{
printf("Move %d: from %c to %c\n",n,a,b);
}
五、测试分析: