一、介绍
给定三根柱子,记为 A,B,C ,其中 A 柱子上有 n 个盘子,从上到下编号为 1 到 n ,且上面的盘子一定比下面的盘子小。问:将 A 柱上的盘子经由 B 柱移动到 C 柱最少需要多少次?
移动时应注意:
① 一次只能移动一个盘子
②大的盘子不能压在小盘子上
二、递归解题
- 第一步, 将A上面的n-1个盘子借助C柱移动到B柱。
- 第二步, 将A上面的最后的(最大的)盘子移动到C柱 。
- 第三步, 将B上面的所有盘子(n-1)个盘子借助A柱移动到C柱 。
示例(三个盘子)
(1)到(2),(3)到(4)也是一次递归
(1)到(2)
以b为目标,c为缓冲。(3)到(4)
以c为目标, a为缓冲。
以下是(1)到(2)
代码如下:
#include<stdio.h>
void hanoi(int n, char from, char temp, char to)
{
if (n == 1)
{
printf("move disk %d from %c to %c\n", n, from, to);
}
else
{
hanoi(n - 1, from,to, temp);//a到b,那c就是缓冲
printf("move disk %d from %c to %c\n", n, from, to);//a到c,那b就是缓冲
hanoi(n - 1, temp, from,to);//b到c,那a就是缓冲
}
}
int main()
{
int n = 0;
scanf("%d", &n);//盘子数
hanoi(n, 'A', 'B', 'C');
return 0;
}
- 打印结果中数字越大,盘子越大。
- 代码中的注释是针对第一次递归,之后的递归传入的参数在变化,c不一定是缓冲。
- 我们发现一个盘子时需要移动一次,两个盘子时需要移动3次,3个盘子时需要移动7次,所以总结规律:n个盘子需要移动的次数是 2ⁿ-1 次。
F(n)=1+2×F(n-1)
F(n)+1=2×(F(n-1)+1)
因为F(n)+1首项是2,所以F(n)+1是2ⁿ。
三、非递归(暂时不会)
等学了数据结构再来补充。