递归经典例题:汉诺塔问题

目录

 

 问题描述

分析问题

解决问题

总结


 问题描述

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

分析问题

当我们刚看到这道题目时,感觉计算过程会有点复杂,可是如果把问题简化到更小规模的问题,以此确定递归关系,这道题的解法就会变得十分简单。题目中给定的圆盘个数为64片,不妨我们从只放一片圆盘开始慢慢寻找规律,从而解决这个汉诺塔问题。

现在有三个柱子分别为A、B、C,当A初始只有一片圆盘只需从A → C 即可满足。传递次数为1次

递归经典例题:汉诺塔问题_第1张图片

当A初始有2片圆盘时,只需先将A → B,再将A → C,最后将B → C 即可满足。传递次数为3次

递归经典例题:汉诺塔问题_第2张图片

那我们如果在A初始有3片圆盘,会是怎样的传递方式呢?

递归经典例题:汉诺塔问题_第3张图片

传递方式:A→C,A→B,C→B,A→C,B→A,B→C,A→C 总共传递了7次。

从这三个图可以看出,如果A初始有n片圆盘,

传递次数为2^n -1次,

传递规律:我们不考虑中途传递细节,满足最终要求,由大问题分成三大步来解决

  1. 先将n-1个圆盘从第一根柱子A移到第二根柱子B,
  2. 其次将第n个圆盘(最大的圆盘)从第一根柱子A移到第三根柱子C,
  3. 最后将n-1个圆盘从第二个柱子B移到第三个柱子C,即可满足条件。

递归经典例题:汉诺塔问题_第4张图片

解决问题

由以上步骤可知:为了解出n层汉诺塔,要使用n-1层汉诺塔的解法,即运用递归算法解决问题,代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include 
void move(char pos1,char pos2)
{
	printf(" %c->%c ",pos1,pos2);
}
/*
N:代表盘子的个数
pos1:起始位置
pos2:中转位置
pos3:目的位置
*/
void Hanoi(int n,char pos1,char pos2,char pos3)
{
	if (n == 1)
	{
		move(pos1,pos3);
	}
	else
	{
		Hanoi(n-1,pos1,pos3,pos2);
		move(pos1, pos3);
		Hanoi(n-1,pos2,pos1,pos3);
	}
}
int main()
{   
    int m;
    printf("请输入汉诺塔层数:");		
	scanf("%d", &m);	
	Hanoi(m, 'A', 'B', 'C');
	return 0;
}

当m=4时,程序结果为

递归经典例题:汉诺塔问题_第5张图片

总结

递归问题是个抽象的问题,因为人大脑计算堆栈是有限的,想象不出来运行效果,因此我们只需要枚举前几个实例,然后寻找其中规律即可。当n值增大时,只是复杂度发生了改变,实际上函数的递归调用还是一样的。慢慢来,说不定哪天自己理解透了呢~

如有补充或存在问题请在评论区留言哟~

你可能感兴趣的:(汉诺塔问题,算法,递归算法,c语言)