经典递归问题——汉诺塔(c语言实现)
问题背景
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。
问题分析
假设有n个盘子
代码的实现主要分为三个步骤
1:将A的n-1个盘子借助C移动到B上,
2:再将A中最后的一个大盘子移动到C上
3: 将B的n-1个盘子借助A移动到C上
递归分析图
核心代码
if (1 == n)
move(A, C); //当盘子个数只有一个时,直接从A移动到C,(递归限制条件)
else
{
Hanoi(A, C, B, n - 1);//由起始地址A通过周转地址C将n-1个盘子移动到B
move(A, C);//将最后一个盘子移动到C
Hanoi(B, A, C,n - 1);//将B中的n-1个盘子通过周转地址A移动到C
}
注:使用递归函数最重要的是要有一个递归中止条件,不然会出现死递归的现象
完整代码:
#include <stdio.h>
void move(char b,char c)//移动函数
{
printf("%c --> %c\n",b ,c );
}
void Hanoi(char A, char B, char C, int n)
{
if (1 == n)
move(A, C); //当盘子个数只有一个时,直接从A移动到C,(递归限制条件)
else
{
Hanoi(A, C, B, n - 1);//由起始地址A通过周转地址C将n-1个盘子移动到B
move(A, C);//将最后一个盘子移动到C
Hanoi(B, A, C,n - 1);//将B中的n-1个盘子通过周转地址A移动到C
}
}
int main()
{
int a = 0;
printf("盘子个数-->");
scanf("%d", &a);
Hanoi('A', 'B', 'C', a);
return 0;
}
运行结果
体会
递归函数比较抽象,学习起来会比较困难;最好的方法就是画一下递归展开图,将每次递归时传参的值和结束时返回的值标出来(自己画的递归展开图太丑了,就去别的地方copy了一张),如有错误,还请指正。