【C语言】汉诺塔 —— 详解

一、介绍

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

面试题 08.06. 汉诺塔问题 - 力扣(LeetCode)


二、问题描述

有 A,B,C 三根柱子,A 上面有 n 个盘子,我们想把 A 上面的盘子移动到 C 上,但是必须要满足以下三个条件:

  • 每次只能移动一个盘子;
  • 盘子只能从柱子顶端滑出移到下一根柱子;
  • 盘子只能叠在比它大的盘子上。

三、解题思路

这是一道递归方法的经典题目。

1、如果 n = 1,只有一个盘子,那么就直接将它从 A 移到 C 上

2、如果 n = 2,这时我们就需要借助 B,因为小盘子必须时刻都在大盘子上面,共需要 4 步


3、如果 n > 2,思路和上面是一样的。我们将 n 个盘子看成两个部分,一部分有 1 个盘子,另一部分有 n-1 个盘子

可是,那 n-1 个盘子是如何从 A 移动到 B 再移动到 C 的呢?

将最初的 n 个盘子从 A 移到 C 的问题,转化成了将 n-1 个盘子从 A 移到 C 的问题, 以此类推,直至转化成 1 个盘子的问题时,这个问题也就解决了。这里利用了分治的思想。

  1. 当 n = 1 时,直接将盘子从 A 移到 C 上;
  2. 当 n > 1 时,
  • 先把上面的 n-1 个盘子从 A 借助 C 移动到 B(化为子问题,进行递归);
  • 再将 A 上最后一个盘子从 A →C;
  • 再将 B 上 n - 1 个盘子从 B 借助 A 移动到 C(化为子问题,进行递归)。

四、代码

cpp 复制代码
#include<stdio.h>

void move(char A, char C, int n)
{
	printf("把第%d个圆盘从%c------>%c\n", n, A, C);
}

void HanoiTower(char A, char B, char C, int n)
{
	if (n == 1)
	{
		move(A, C, n);
	}
	else
	{
		// 1.把A上n-1个圆盘从A柱借助C移动到B上
		HanoiTower(A, C, B, n - 1);

		// 2.将A最后一个圆盘从A->C
		move(A, C, n);

		// 3.把B上n-1个圆盘从B借助A移动到C上
		HanoiTower(B, A, C, n - 1);
	}
}

int main()
{
	int n = 0;
	printf("输入A柱上的圆盘的个数:");
	scanf("%d\n", &n);

	//将n个圆盘从A柱借助B柱移动到C柱上
	HanoiTower('A', 'B', 'C', n);

	return 0;
}

五、扩展

如果想要计算移动了多少次盘子 ,只需要加入多一个move() 函数即可。

相关推荐
麦序子2 分钟前
用 Python + python-docx 批量生成带表格样式的装修报价单 Word 文档(含合计公式)
开发语言·python·自然语言处理·word·python3.11
1-1=012 分钟前
Python PyCharm
开发语言·python·pycharm
牛肉胡辣汤16 分钟前
Blender + Three.js 开发讲解:从 .blend 到能转的产品页
开发语言·javascript·blender
惊讶的猫18 分钟前
Spring AOP
java·开发语言
fanged25 分钟前
Audio学习4(DSP)(TODO)
学习
小莞尔27 分钟前
【51单片机】【protues仿真】基于51单片机超声波测距仪系统
c语言·单片机·嵌入式硬件·物联网·51单片机
ii_best37 分钟前
按键精灵手机助手 v5.2.1 实测:inputText 逐字延时 + 调试面板多行复制,安卓脚本开发的两个输入痛点一次解决
android·开发语言·智能手机·自动化·ai编程·按键精灵
波力海苔夹心脆67540 分钟前
C# StringBuilder 详解:字符串拼接为什么总说要用它?
开发语言·笔记·c#·.net·字符串·stringbuilder·入门教程
lengxuenong1 小时前
树状数组 · 信息学学习手册3-优化LIS
c++·学习·算法
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 今日佳人:需求分析
java·开发语言·交友