介绍
汉诺塔问题是一个经典的递归问题,源自印度传说。问题的描述是:有三根柱子,A、B、C,A柱上有从小到大的n个圆盘,要求把这些圆盘从A柱移动到C柱,期间可以借助B柱,但有一个限制条件:任何时候都不能将一个较大的圆盘放在较小的圆盘上。
解决方案
解决汉诺塔问题的方法采用递归的思想。我们可以定义一个递归函数,根据汉诺塔问题的性质,将问题划分为三个步骤:
- 将n-1个圆盘从A柱经过C柱移动到B柱。
- 将最大的圆盘从A柱移动到C柱。
- 将n-1个圆盘从B柱经过A柱移动到C柱。
这个递归的过程会一直进行下去,直到只剩一个圆盘时,就可以直接移动到目标柱。整个递归的过程中,我们统计移动次数,即解决问题的步骤数。
代码
#include <stdio.h>
// 计算汉诺塔移动次数的函数
int ci_shu(int n);
// 汉诺塔移动过程的函数
void cao_zhuo(int n, char start, char end, char process);
// 全局变量,用于统计移动次数
int a = 0;
int main()
{
int n;
scanf("%d", &n);
// 调用汉诺塔移动过程函数
cao_zhuo(n, 'A', 'B', 'C');
// 输出移动次数
printf("sum == %d \n", a);
return 0;
}
// 递归计算汉诺塔移动次数的函数
int ci_shu(int n)
{
if (n == 1)
{
return 1;
}
else
{
return 2 * ci_shu(n - 1) + 1;
}
}
// 汉诺塔移动过程的递归函数
void cao_zhuo(int n, char start, char end, char process)
{
// 如果只有一个盘子,直接移动即可
if (n == 1)
{
a++; // 移动次数加一
printf("%c --> %c\n", start, end);
return;
}
else
{
// 将n-1个盘子从起始柱移动到辅助柱
a++; // 移动次数加一
cao_zhuo(n - 1, start, process, end);
// 将剩余的一个盘子从起始柱移动到目标柱
a++; // 移动次数加一
printf("%c --> %c\n", start, end);
// 将n-1个盘子从辅助柱移动到目标柱
a++; // 移动次数加一
cao_zhuo(n - 1, process, end, start);
}
}