目录
一. 首先,何为汉诺塔问题?
简单来讲,汉诺塔问题是这样的:
给定三根柱子,记为A B C ,其中 A柱子上有 n个盘子,从上到下编号为 0 到 n−1 ,且上面的盘子一定比下面的盘子小。问:将 A柱上的盘子经由 B 柱移动到 C 柱最少需要多少次?
移动时应注意:① 一次只能移动一个盘子
②大的盘子不能压在小盘子上
二.解题思路
用递推的方法,我们需要先确定ABC三个柱子的角色,A是起始位置,B是中转位置,C是目的位置。然后再考虑如何将A上的所有盘子移动到C上,又得随时保证大盘子在下面小盘子在上面,那么我们要思考如何将最大的盘子先放到C上。
我们先拿最简单的一层汉诺塔做例子,我们只需要将盘子直接由A移动到C就可以了。
我们再拿三层汉诺塔做例子,我们先将最小的盘子移动到C,再将中盘子移到B,再将小盘子移动到B,再将大盘子移动到C盘子,再将小盘子移动到A,最后将中,小盘子按大小放到C,到此三层汉诺塔问题就解决了。
由上面两个例子可以看出一层就汉诺塔最特殊,可以看作单独一个和二层汉诺塔以上的作区分,我们观察二层以上汉诺塔也可以得到一个规律 :假设有n层汉诺塔,我们只需要将一次将n-1到第1个盘子到都放到B上,再将第n个盘子放到C上,最后将其他盘子依次都放到C上就好了。
三.代码实现
根据上面这些我们就可以写一个函数来定义这两种情况
void hanoi(int n,char a,char b,char c)//a,b,c为汉诺塔的柱子数
{
void move(char x, char y);
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("%c-->%c\n", x, y);
}
最后我们再把主函数写出来就好了。
void hanoi(int n, char a, char b, char c);
int m;
printf("input the number of desks:");//输入层数
scanf("%d", &m);//输入层数
printf("the step to move %d desk:\n", m);//输出移动步骤
hanoi(m, 'A', 'B', 'C');
四。完整代码展示
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void hanoi(int n,char a,char b,char c)
{
void move(char x, char y);
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("%c-->%c\n", x, y);
}
int main()
{
void hanoi(int n, char a, char b, char c);
int m;
printf("input the number of desks:");
scanf("%d", &m);
printf("the step to move %d desk:\n", m);
hanoi(m, 'A', 'B', 'C');
return 0;
}