汉诺塔是非常有意思的递归问题,我第一次接触还不理解,把问题拖延到半年后至今才理解,因为我最近学到数据结构里的二叉树,二叉树有非常多的例题是用递归实现的,例如求二叉树节点数,求最大深度,当我理解了一个又一个二叉树递归题,我突然觉得汉诺塔问题应该不难了,于是我把递归图大致画出来,然后我就对汉诺塔理解的七七八八了,貌似接来下就细说我是如何理解的汉诺塔问题。
汉诺塔的问题就是把这n个盘子从起始处移动到终点柱,由题得,盘子在任意柱上都应该是大盘子在下,小盘子在上,所以n个盘子要想到终点柱那第n个盘子就要先到终点柱,那盘子中n-1个就要移开,第n个盘子才能移动到终点柱,
此时起始柱无盘子,n-1个盘子在中转柱上,第n个已经直接移动到目标柱子上,接下来我们就是把中转柱的n-1个盘子移动到终点柱,第n-1个盘子还是要先到目标柱,所以要把n-2个盘子移动到起始柱放着,再把第n-1个盘子移动到目标柱,注意:此时对于这n-1个盘子来说,起始柱变为了B柱,中转柱是A柱,但目标柱还是C柱。(该递归问题中最需要注意的就是起始柱,目标柱和中转柱是不停交换的)
#include<stdio.h>
void Move(char start, char terminal, int n)
{
printf("把第%d个盘子从%c移动到%c\n", n, start, terminal);
}
void Hanoi(char start, char transfer, char terminal, int n)
{
if (n == 1)//当只剩一个盘子时,直接移动即可
{
Move(start, terminal, n);
return;
}
//第一步,将n-1个盘子移动到中转柱,此时对于这n-1个盘子来说,
//移动这n-1个盘子,起始柱是不变的,但目标柱和中转柱要交换
因为对于不同时期移动盘子目标柱是不一样的
Hanoi( start, terminal, transfer, n-1);
//第二步把第n个盘子移动到目标柱
Move(start, terminal,n);
//第三步,把已经移动到中转柱B的n-1个盘子移动到目标柱,
此时调用Hanoi函数起始处变为transfer
Hanoi(transfer,start,terminal, n - 1);
}
int main()
{
//汉诺塔问题
char start = 'A';
char transfer = 'B';
char terminal = 'C';
int n = 0;
scanf("%d", &n);//输入起始点要移动的盘子数
Hanoi(start, transfer, terminal,n);//起始处n个盘子借助中转处将盘子移动到目标柱
}