目录
一、汉诺塔的玩法
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
二、汉诺塔的逻辑
现将三个柱子分别记为A起始位置、B中转位置、C目标位置。n表示圆盘的个数。
1、当汉罗塔层数n为1层时(如下图)
当汉诺塔的层数为1时很简单,直接从起始位置A到目标位置C。
第1次:A---->C
2、当汉罗塔层数n为2层时(如下图)
思考一下2个圆盘时的移动步骤,也很简单。总共需要3步:第1步,把小圆盘从A移到B;第二步,把大圆盘从A移到C;第三步,把小圆盘从B移到C。
第1次:A---->B
第2次:A---->C
第3次:B---->C
3、当汉诺塔层数n为3层时(如下图)
我们来思考一下,要想把3个圆盘从A移到C,首先需要把3号上面的圆盘1和2移到B,这样3号才能直接到C。
关键点是,我们把1、2两个圆盘移到B,不就是我们之前讨论的2个圆盘的情况吗?只不过之前的目标是从A移到C,现在是从A移到B,同样是2个空着的杆子,仅仅是编号有差别,本质没有任何区别!
理解了上面所讲的内容,我们的思路就变得很明白了。3个圆盘同样可以认为是3大步:第1步,把1和2移到B;第2步,把3移到C;第3步,把1和2从B移到C。而其中1和2如何移到B或者C,就是我们之前讨论的2个圆盘的情况了,这也就是递归的思想。
4、 当汉诺塔层数为n时(如下图)
目前A上有n个圆盘,我们要把它们移到C上。这个其实也只需要3步:第1步,把A中从1到n-1个圆盘移到B;第2步,把A中剩下的第n个圆盘移到C;第3步,把B中的n-1个圆盘移到C。至于如何把n-1个圆盘移到B,那就相当于重复我们上面的步骤,直到递归到我们熟悉的2个或3个圆盘所需的移动步骤。
三、代码实现
1、Java代码实现
import java.util.Scanner;
public class Hanoi{
//定义移动的次数,初值为0
static int count=0;
//A-起始位置
//B-中转位置
//C-目标位置
public static void hanoi(int n,String A,String B,String C){
//判断层数n是否小于1,小于1则报错
if(n<1){
System.out.println("请输入大于等于1的整数!");
//判断层数n是否等于1,等于1则1次就移动完毕
}else if(n==1){
count++;
System.out.println("第"+count+"次:"+A+"---->"+C);
//当层数n大于1时执行下面的操作
}else {
//将n-1个盘子从A通过C移到B
hanoi(n-1,A,C,B);
//移动次数加1
count++;
System.out.println("第"+count+"次:"+A+"---->"+C);
//将n-1个盘子从B通过A移到C
hanoi(n-1,B,A,C);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入汉诺塔的层数:");
int n=sc.nextInt();
hanoi(n,"A","B","C");
}
}
2、C语言实现
#include <stdio.h>
//定义移动的次数,初值为0
static int count = 0;
// A-起始位置
// B-中转位置
// C-目标位置
void hanoi(int n, char A, char B, char C)
{
//判断层数n是否小于1,小于1则报错
if (n < 1)
{
printf("请输入大于等于1的整数!");
}
//判断层数n是否等于1,等于1则1次就移动完毕
else if (n == 1)
{
count++;
printf("第%d次:%c---->%c\n", count, A, C);
}
//当层数n大于1时执行下面的操作
else
{
//将n-1个盘子从A通过C移到B
hanoi(n - 1, A, C, B);
//移动次数加1
count++;
printf("第%d次:%c---->%c\n", count, A, C);
//将n-1个盘子从B通过A移到C
hanoi(n - 1, B, A, C);
}
}
void main()
{
int n;
printf("请输入汉诺塔的层数:\n");
scanf("%d", &n);
hanoi(n, 'A', 'B', 'C');
}
3、Python实现
//因为python不支持静态变量,所以我引入类,然后调用这个类的变量
class MyStatic:
count=0
def hanoi(n,A,B,C):
if n<1:
print("请输入大于等于1的整数!")
elif n==1:
//移动次数加1
MyStatic.count+=1
print("第",MyStatic.count,"次:",A,"---->",C)
else:
//将n-1个盘子从A通过C移到B
hanoi(n-1,A,C,B)
//移动次数加1
MyStatic.count+=1
print("第",MyStatic.count,"次:",A,"---->",C)
//将n-1个盘子从B通过A移到C
hanoi(n-1,B,A,C)
n=eval(input("请输入汉诺塔的层数:\n"))
hanoi(n,'A','B','C')
count = 0
def hanoi(n, A, B, C):
global count
if n < 1:
print("请输入大于等于1的整数!")
elif n == 1:
count += 1
print("第{}次:{}---->{}".format(count, A, C))
else:
hanoi(n - 1, A, C, B)
count += 1
print("第{}次:{}---->{}".format(count, A, C))
hanoi(n - 1, B, A, C)
if __name__ == '__main__':
n = int(input("请输入汉诺塔的层数:"))
hanoi(n, "A", "B", "C")
四、运行结果
五、总结
本文主要介绍了汉诺塔的玩法、逻辑、以及相关代码的实现。主要的思想是递归思想。本文也许还有许多不足的地方,欢迎各位大佬指点。若本文对你有所帮助,请支持我,给予我记录更多文章的动力。 感谢!