一、汉诺塔
汉诺塔的玩法:有A,B,C三根柱子和一些大小不一的圆盘,最初这些圆盘按大小顺序叠放在一根柱子上,最大的在最下面,最小的在最上面。游戏的目标是将所有圆盘从一个柱子移动到另一个柱子上。
期间需遵守以下规则:
每次只能移动一个圆盘。
大圆盘不能放在小圆盘之上。
可以使用中间的柱子来暂存圆盘,以完成最终的移动目标。
二、递归
函数在运行过程中不断调用自己,把一个大问题分解成几个小问题来逐个解决。
对于n个圆盘的汉诺塔问题,可以分解为将上面的n-1个圆盘从起始柱子移动到辅助柱子的问题,然后将最大的圆盘(第n个圆盘)移动到目标柱子,最后将那n-1个圆盘从辅助柱子移动到目标柱子。这个过程可以不断重复,直到所有圆盘都被成功移动到目标柱子上。
功能函数如下:
void hanoi(int n, char A, char B, char C)
{
if (n == 1)
{
printf("Move sheet %d from %c to %c\n", n, A, C);
}
else
{
hanoi(n - 1, A, C, B);
printf("Move sheet %d from %c to %c\n", n, A, C);
hanoi(n - 1, B, A, C);
}
}
当只有一个圆盘时,圆盘直接从A柱到C柱,当有多个圆盘时,需要先将除最后一个圆盘以外的其它圆盘通过C柱转移到B柱,由 hanoi(n-1,A,C,B) 完成,记为A递归,之后将最后一个圆盘(n)转移到C柱,之后再将B柱的圆盘通过A柱转移到C柱,由 hanoi(n-1,B,A,C) 完成,记为B递归,如此转移完成。
代码运行过程
我这里以当n=3为例,为方便理解,此时记为(1)。

当n=3时,直接执行else,这时发生一次A递归,BC柱调换位置。(2)

n=2,继续else,发生A递归,BC柱调换位置。(3)

n=1,执行语句,1盘 从 A 到 C,此时(3)执行完,返回(2),继续执行指令,2盘 从 A 到 B,之后进行B递归,AB柱调换位置。(4)

n=1,执行语句,1盘 从 C 到 B,此时(2)执行完后返回(1),执行指令,3盘 从 A 到 C,之后进行B递归,AB柱调换位置。(5)

n=2,继续else,发生A递归,BC柱调换位置。(6)

n=1,执行语句,1盘 从 B 到 A,此时(6)执行完后返回(5),执行指令,2盘 从 B 到 C,之后进行B递归,AB柱调换位置。(7)

n=1,执行语句,1盘 从 A 到 C,此时程序完成
总体代码如下:
#include <stdio.h>
void hanoi(int n, char A, char B, char C)
{
if (n == 1)
{
printf("Move sheet %d from %c to %c\n", n, A, C);
}
else
{
hanoi(n - 1, A, C, B);
printf("Move sheet %d from %c to %c\n", n, A, C);
hanoi(n - 1, B, A, C);
}
}
int main()
{
int n;
printf("请输入盘数:");
scanf("%d", &n);
hanoi(n, 'A', 'B', 'C');
return 0;
}
2万+

被折叠的 条评论
为什么被折叠?



