【递归之经典问题】汉诺塔

文章目录

  • 题目
  • 思路
  • 代码
  • 总结

题目

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

思路

一个盘子
A移动到C
1步完成

再来看2个盘子
【递归之经典问题】汉诺塔_第2张图片
1-》A上的盘子移到B
2-》A上的盘子移动到C
3-》B上的盘子移动到C
3步完成

看3个盘子
【递归之经典问题】汉诺塔_第3张图片
上面2个看成整体,将整体移动到B,将最下面一个移动到C,再将B上的整体移动到C
1-》A移动到C
2-》A移动到B
3-》C移动到B
此时完成AB整体移动到B
4-》A移动到C
最后将AB移动到C
5-》B移动到A
6-》B移动到C
7-》A移动到C
7步完成

【递归之经典问题】汉诺塔_第4张图片

以此类推
N个盘子2^N - 1次完成
当需要移动n个盘子时可以一共看成3大步
1-》A上的n-1看成整体移到B 此时需要借用中间位置位置 C
2-》将A上最后一个移动到C
3-》将B上n-1个盘子移动到C 此时需要借用中间位置 A
原来是将n个盘子从一个地方移动到另一个地方
现在只需要将n-1个盘子从一个地方移动到另一个地方
这里体现了递归的化大为小

代码

#include
//汉诺塔问题
void move(char from, char end) //移动盘子函数,从from移动到end
{
	printf("%c->%c\n", from, end);
}

void Hanio(int plate_num, char from, char mid, char end) //从from 借用 mid 移动到end
{
	if (1 == plate_num)	//当最后只剩下一个盘子时,将最大的一个盘子从from移动到end
	{
		move(from, end);
	}
	else //剩下的不止一个盘子 //分为三大步 
		//1.n-1个盘子移动到中间位置mid ,此时中间位置mid变成第1步的目标位置,end变成第1步的中间位置
		//2.最大的一个盘子从起始位置移动到目标位置 
		//3.n-1个盘子从中间位置mid移动到目标位置,此时mid变为第3步的起始位置,from变成第3步需要借用的中间位置
	{
		Hanio(plate_num - 1, from, end, mid); //实现第一步
		move(from,end); //实现第二步
		Hanio(plate_num - 1, mid, from, end); //实现第三步
	}
}
int main()
{
	int plate_num = 0;
	scanf("%d", &plate_num);
	Hanio(plate_num, 'A', 'B', 'C');
	return 0;
}

【递归之经典问题】汉诺塔_第5张图片

总结

递归的中心思想就是将大事化小,并且解决方法相似,汉诺塔问题将移动n个盘变成移动n-1个盘子的问题,并且移动的方法类似,都是从某个位置借用中间位置移动到目标位置。

你可能感兴趣的:(题,算法,c语言,回归算法,开发语言)