汉诺塔问题(递归版)

319 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第四天

在这里插入图片描述

@TOC

一、前言

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

:point_right::point_right::point_right:点我即玩,为了更好的理解汉诺塔,大家可以先体验一下

二、问题刨析(详解)

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

:snowflake::snowflake::snowflake:给大家用图片的形式展示了一下汉诺塔的基本流程,说白了,就是一块板上有三根针 A、B、C。 A 针上套有 64 个大小不等的圆盘,按照大的在下、小的在上的顺序排列,要把这 64 个圆盘从 A 针移动到 C 针上,每次只能移动一个圆盘,移动过程可以借助 B 针。

三、移动次数

==设想一下,移动64个汉诺塔需要多少次==据统计,移动64个汉诺塔可能需要几百年,那么我们想要解决汉诺塔问题,该如何使用递归解决了,请看下文:

塔数步数
11
23
37
415
......
642^64-1

:sunny::sunny::sunny:列举了几组数据之后,可以发现每次移动的次数都是2^n-1,所以移动次数代码实现如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int F(int n) {
	if (1 == n)
		return 1;
	else return 2 * F(n - 1) + 1;
}
int main() {
	int n = 0;//n为汉诺塔的层数
	scanf("%d", &n);
	int ret = F(n);
	printf("%d", ret);
	return 0;
}

四、移动步骤

如果只有一个汉诺塔,那么直接从A->C

在这里插入图片描述

如果有两个汉诺塔,即A->B,A->C,B->C三步 在这里插入图片描述

在这里插入图片描述

当汉诺塔数量增多时,列举已经变得十分繁琐,下面直接由递归代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void Hanio_Step(int n, char A, char B, char C)
{
	if (1 == n) //当只有一个一个塔时,直接	A->C
		printf("%c->%c", A, C);
	else   //当塔的数量大于1时,用递归实现
	{
		Hanio_Step(n-1, A, C, B);  //先将A上面的n-1个,借助C,移动到B上
		printf("%c->%c ", A, C);    //剩余1个直接A->C
		Hanio_Step(n-1, B, A, C);  //再将B上面的n-1个,借助A,移动到C上重复循环
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);//输入汉诺塔的个数
	Hanio_Step(n, 'A', 'B', 'C');//用字符A,B,C分别代表三个柱子
	return 0;
}

在这里插入图片描述

总结

相信看到这里的小伙伴对汉诺塔的问题已经有了一定的认识。如果大家感到对自己有帮助的话,记得三连哦,笔芯:heartpulse::heartpulse::heartpulse:

在这里插入图片描述