汉诺塔问题代码写法的详细解析

汉诺塔游戏规则:

规则:

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

这篇文章不讲汉诺塔的玩法和实现过程,只讲代码为何那么写,又是怎样一步一步实现的。其他的基础你们可以去搜索引擎搜索

其实汉诺塔问题难不是难在理解,而是难在程序编写的时候,很多人理解了汉诺塔的游戏规则也知道怎么去操作,但是在写代码的时候就懵了,下面举个代码的例子(其他语言也是一样的,重要的是先了解思路)

很多人是在参数变换这里不理解,下面我会一步一步的来解析代码每一步的执行过程以及为什么要变换柱子

我们先举例两个圆盘的情况

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

void hannuota(int n,char A,char B,char C){
	if(n == 1)
		printf("将编号为 %d 的盘子直接从 %c 柱子移动到 %c 柱子\n",n,A,C);
	else{
		hannuota(n-1,A,C,B);
		printf("将编号为 %d 的盘子直接从 %c 柱子移动到 %c 柱子\n",n,A,C);
		hannuota(n-1,B,A,C);
	}
}

int main(){
	hannuota(2,'A','B','C'); 
	return 0;
} 

代码解析:

调用汉诺塔函数,首先我们传入的盘子数是 2 ,定义三根柱子分别为 A、B、C,进入函数后对 n 进行判断,由于 n > 1,所以执行 else 的代码块,递归调用汉诺塔函数,把 n-1 传入,并且 A -> A,B -> C,C -> B。这里三根柱子变了,至于为什么变,我们接着往下分析。

第一次递归的时候由于 2-1=1 所以满足 if 条件,那么就执行 printf 语句,注意了,此时的柱子是变了的 A -> A,B -> C,C -> B 你可以把三根柱子理解为变量,里面保存的值变了。

打印这条语句的时候,由于 A 保存的值是 A,C 保存的值是 B,n == 1,所以打印的结果就是**"将编号为 1 的盘子直接从 A 柱子移动到 B 柱子"** ,这样,else 代码块中的第一条代码就执行完成了,接下来执行第二条代码,用 printf 打印一条信息,注意了,这里的 n,A,B,C 是主函数里传进来的值,也就是说 n = 2 ,A = A,B = B,C = C,所以打印的结果是**"将编号为 2 的盘子直接从 A 柱子移动到 C 柱子"**,接着调用第三条代码,第二次递归,因为次时的盘子位置如下图所示:

还需要进行移动,把 n-1,A = B,B = A,C = C,传给递归函数,因为 2-1 满足 if 语句,所以直接打印**"将编号为 1 的盘子直接从 B 柱子移动到 C 柱子"**。至此结束。

上述就是两个盘子的汉诺塔详细的代码实现过程,n 个盘子的实现结果也是和上面一样的分析法,核心代码不需要变

cpp 复制代码
if(n == 1)
		printf("将编号为 %d 的盘子直接从 %c 柱子移动到 %c 柱子\n",n,A,C);
	else{
		hannuota(n-1,A,C,B);
		printf("将编号为 %d 的盘子直接从 %c 柱子移动到 %c 柱子\n",n,A,C);
		hannuota(n-1,B,A,C);
	}

这里给大家说一下,这种递归的题是很抽象的,没必要每种情况都去详细分析,那样太复杂,刚开始学的话容易把自己绕晕,你只需要详细了解两三个盘子的情况下代码是怎么跑的这就够了。大家按照我上面的分析方法自己试着去分析三个盘子的情况,能分析出来证明你理解了,然后就过。

相关推荐
珹洺2 分钟前
C++从入门到实战(十三)C++函数模板与类模板初阶讲解
开发语言·数据结构·c++·算法
geneculture3 分钟前
金融的本质是智融、融资的实质是融智、投资的关键是投智,颠覆传统金融学的物质资本中心论,构建了以智力资本为核心的新范式
大数据·人工智能·算法·金融·系统工程融智学
计算机小手2 小时前
全格式文档转 Markdown 工具,Docker 一键部署,支持 API 调用
经验分享·开源软件
yuhao__z4 小时前
代码随想录算法训练营第五十六天| 图论2—卡码网99. 岛屿数量(dfs & bfs)
算法·深度优先·图论
小wanga4 小时前
【算法专题十】哈希表
算法·哈希算法·散列表
一支闲人7 小时前
C语言初阶:函数的嵌套调用、链式访问、声明、定义、递归
c语言·c语言基础知识·适用于新手小白
S01d13r7 小时前
LeetCode 解题思路 45(分割等和子集、最长有效括号)
算法·leetcode·职场和发展
理想奋斗中8 小时前
【LeetCode Hot100 | 每日刷题】二叉树的层序遍历
算法·leetcode·bfs
JCBP_9 小时前
C++(1)
开发语言·c++·算法
jie188945758669 小时前
C语言中,const关键字用法,详细解读
c语言·开发语言