详解汉诺塔问题
问题渊源:
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
问题描述:
有A,B,C三根柱子,在A上套有n个圆盘,问如何将盘子从A移到C上。
要求:一次只能移动一个盘子,且小的在大的上面。
输入样例:
3
输出样例
A ----> C
A ----> B
C ----> B
A ----> C
B ----> A
B ----> C
A ----> C
-------------------------------------------------------------华丽的分割线-------------------------------------------------------------
分析:
若 n = 1 时:
A ----> C
即:将最大的直接从A移动到C
若 n = 2 时:
A ----> B
A ----> C
B ----> C
即:
- 将最上面的1个盘从A移到B上
- 将最大的移到C上
- 将最上面的1个盘从B移到C上
若 n = 3时:
A ----> C
A ----> B
C ----> B
A ----> C
B ----> A
B ----> C
A ----> C
即:
- 将最上面的2个盘从A移到B上
- 将最大的移到C上
- 将最上面的2个盘从B移到C上
若n = N时:
我们可以从上面的分析看出一个移到的规律:
- 将最上面的N - 1个盘从
A移到B
上 - 将最大的盘从
A移到C
- 将最上面的N - 1个盘
从B移到C
上
其中最繁琐的是第1,3步。
但是,第一步亦可以看作是一个新的N - 2阶的汉诺塔,所以第一步的移动方法为:
- 将最上面的N - 2个盘
从A移到C
上 - 将最大的盘
从A移到B
- 将最上面的N - 2个盘
从C移到B
上
所以,很明显汉诺塔问题可以用递归来解决,即:f(n) = f(n-1) 的规律来解题。
但是,如何实现呢?总不能只是 f(n) = f(n-1) 一直到 f(1) 吧。
所以,我们再回过来看一遍,同时构思这个递归函数的大概结构
与需要的参数
。
首先,一定要知道当前递归层数的N值,所以首先有:
void HanoiTower(N)
{
if(N == 1)
{
...
}
else
{
...
}
}
会过来再想想那个规律:
- 将最上面的N - 1个盘从
A移到B
上 - 将最大的盘从
A移到C
- 将最上面的N - 1个盘
从B移到C
上
我们可以将 A <=> 起始柱; B <=> 辅助柱; C <=> 目标柱
所以,该规律可以进一步抽象为:
- 将最上面的
N - 1
个盘从起始柱 移到 辅助柱上 - 将
最大
的盘从起始柱 移到 目标柱 - 将最上面的
N - 1
个盘从辅助柱 移到 目标柱 上
!!!注:从整体上看,完成N阶汉诺塔,A <=> 起始柱; B <=> 辅助柱; C <=> 目标柱
!!!
!!!但是,当完成第一步 “将最上面的N - 1个盘从A 移到B上”时,B <=> 目标柱; C <=> 辅助柱
!!!
所以,这个递归函数还需知道起始柱
辅助柱
目标柱
三个参数
#include<stdio.h>
void HanoiTower(int N,char a,char b,char c)
{
if(N == 1)
printf("%c ----> %c\n", a, c);
//我们将参数a, 看作 起始柱
//参数b, 看作 辅助柱
//参数c,看作 目标柱
//!!!!记住是参数a,b,c !!!!
//不是A,B,C,三个实际的柱子
else
{
HanoiTower(N-1, a, c, b);//完成 将N-1从A移动到B上
printf("%c ----> %c\n", a, c);
HanoiTower(N-1, b, a, c);//完成 将N-1从B移动到C上
}
}
int main(void)
{
int N;
scanf("%d", &N);
HanoiTower(N, 'A', 'B', 'C');
return 0;
}
因为朋友的需要,我也提供了Python的源码
Python 也是一样的原理:
def HanoiTower(x,y,z,n):#把n个盘子从x通过y移动到z
if n==1:
print('%s-->%s'%(x,z))
else :
HanoiTower(x,z,y,n-1)
print('%s-->%s'%(x,z))
HanoiTower(y,x,z,n-1)
n = int(input('输入一个整数:'))
HanoiTower('A','B','C',n)
以上便是 关于汉诺塔问题的全部内容了。
感谢阅读!