Hanoi-C
什么是汉诺塔?汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

这是一个可视化的汉诺塔模型,我们完成这个游戏的思路就是要将第一个柱子上的所有圆盘按照从大到小的顺序罗列。
那么假设我们有 n 个圆盘,我们想让第 n 个圆盘移动到 T3 上面,那我们是不是得让 ( N-1) 个盘子移动到 T2 上,这样我们才可以让 N 盘移动到 T3 上。就像这样

那么我们在移动的这个过程中,我们就可以把 T1 叫做起始柱,然后 T2 叫做工具柱。
那现在,我们的 n 盘已经在 T3 上了,然后(N-1)也已经在 T2 上了,现在,T2 就是起始柱,T1 就是工具柱,那我们现在的思路是不是就是让起始柱上的第 n 个盘(哦,感觉不应该叫做第 N 个盘子,应该是第 n-1 个,然后 n-1 上面的盘子应该叫做 n-2,这样才正确) 移动到 T3 上,然后 (n-2)的盘移动到我们的工具柱上。

最后我们将最终的盘子移动到 T3 上就完成游戏了。
那我们用代码来写这道题
首先我们创建一个函数,来执行我们的汉诺塔的逻辑运算
//函数参数声明
/*
声明汉诺塔问题的递归函数
参数:
diskCount: 盘子的数量
sourcePeg: 源柱子
auxPeg: 辅助柱子
targetPeg: 目标柱子
*/
int hanoi(int diskCount, char sourcePeg, char auxPeg, char targetPeg)
{
//如果一个盘子都没有的话,就直接退出。
if(diskCount == 0)
{
return 0;
}
//如果只有一个disk的话,就直接将sourcePeg上的盘子移动到targetPeg上面
if(diskCount == 1)
{
printf("move %c to %c \n", sourcePeg, targetPeg);
}
/*
多个disk的情况
将diskCount-1个盘子从sourcePeg移动到auxPeg上面
将最后一个盘子从sourcePeg移动到targetPeg上面
将diskCount-1个盘子从auxPeg移动到targetPeg上面
递归调用
*/
else
{
hanoi(diskCount - 1, sourcePeg,targetPeg, auxPeg);
printf("move %c to %c \n", sourcePeg, targetPeg);
hanoi(diskCount - 1,auxPeg,sourcePeg,targetPeg);
}
//习惯。
return 0 ;
}
我们只讲讲 else 部分的代码,因为我在这里想了很久,然后也错了一些。
我们知道在汉诺塔里面,我们需要将 N-1 部分的柱子移动到 T1 上,这样才可以将 T1 的 n 柱子移动到 T3,那么我们就可以知道第 32 行的代码为什么是
hanoi(diskCount - 1, sourcePeg,targetPeg, auxPeg);
因为我们 (n-1)的目标柱是 T2,因为我们要将 n-1 全部移动到 T2 上面,所以,此时 T3 为工具柱。
好了,我们现在知道了 32 行的代码逻辑,那么经过了 32 行代码执行后,我们现在(n-1)都在 T2 上,N 在 T3 上,现在我们需要将 N-1 的部分通过 T1 这个辅助柱子来将 n-1 按大到小移动到 T3 上。
所以 34 行的代码为
hanoi(diskCount - 1,auxPeg,sourcePeg,targetPeg);
总代码:
// 汉诺塔问题
/*
声明汉诺塔问题的递归函数
参数:
diskCount: 盘子的数量
sourcePeg: 源柱子(起始柱子)
auxPeg: 辅助柱子(中间柱子)
targetPeg: 目标柱子(最终柱子)
*/
#include "stdio.h"
int hanoi(int diskCount, char sourcePeg, char auxPeg, char targetPeg);
int main()
{
int diskCount;
printf("请输入盘子数:");
scanf("%d", &diskCount);
hanoi(diskCount, 'A', 'B', 'C');
return 0;
}
int hanoi(int diskCount, char sourcePeg, char auxPeg, char targetPeg)
{
//如果一个盘子都没有的话,就直接退出。
if(diskCount == 0)
{
return 0;
}
//如果只有一个disk的话,就直接将sourcePeg上的盘子移动到targetPeg上面
if(diskCount == 1)
{
printf("move %c to %c \n", sourcePeg, targetPeg);
}
/*
多个disk的情况
将diskCount-1个盘子从sourcePeg移动到auxPeg上面
将最后一个盘子从sourcePeg移动到targetPeg上面
将diskCount-1个盘子从auxPeg移动到targetPeg上面
递归调用
*/
else
{
hanoi(diskCount - 1, sourcePeg,targetPeg, auxPeg);
printf("move %c to %c \n", sourcePeg, targetPeg);
hanoi(diskCount - 1,auxPeg,sourcePeg,targetPeg);
}
//习惯。
return 0 ;
}

浙公网安备 33010602011771号