栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言:汉诺塔(经典递归问题)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言:汉诺塔(经典递归问题)

汉诺塔问题介绍

关于汉诺塔的传说:
法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
汉诺塔游戏规则:
现有三根相邻的柱子,标号为A,B,C。其中A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘。
现在要求把所有盘子一个一个移动到柱子C上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方。
游戏图片:

游戏演示

一层汉诺塔

两层汉诺塔

三层汉诺塔

C语言递归解决汉诺塔问题

从刚刚的例子来看,其实汉诺塔还蛮简单的吧? 但是这只是前三层的解法,如果是四层,五层,甚至是100层呢?
好像我们顺着推下去并不能很顺利地解决问题。。。
所以我们提出用递归的方式来解决汉诺塔。

递归思想的介绍

程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式:把大事化小
递归的两个必要条件:
1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
2.每次递归调用之后越来越接近这个限制条件。

注意最后的两句话:把大事化小和递归的条件

递归思想的实现

让我们想一想,100层的汉诺塔,我们肯定是不容易解决的,那我们不妨大事化小,两层的汉诺塔我们可以解决吧?一层的汉诺塔我们可以解决吧?
那我们试着这样想:将除了最后一层的所有方块看成一块,然后借助C柱,将他们转移到B柱,这样是不是就可以把A柱上的最大的那一块转移到C柱上了?最后我们再将B柱上剩下的方块,借助A柱,转移到C柱上,这样就全部搞定了!
即N个盘子的解法:

1.将N-1个方块从A柱借助C杆转移到B柱
2.将A柱上的第N个方块转移到C柱
3.将N-1个方块从B柱借助A柱转移到C柱

图解:

C语言伪代码实现

最终C语言代码
#include 

//统计移动次数
int count = 0;

void hanoi(int n, char a, char b, char c)
{
	if (n == 1)
	{
		printf("move:%c->%cn", a, c);
		count++;
	}
	else
	{
		hanoi(n - 1, a, c, b);
		printf("move:%c->%cn", a, c);
		count++;
		hanoi(n - 1, b, a, c);
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	hanoi(n, 'A', 'B', 'C');
	printf("最终移动次数:%d", count);
}

程序运行结果:

我们可以对照一下上面的GIF图片看看,最后结果应该是一样的。

跟着流程一起过一遍!

最后总结

汉诺塔是一道很经典的递归问题,掌握它能够让我们对递归有更深的体会。如果大家没有看明白的话,可以在编译器中逐步调试,通过监视栈的调用来好好体会一下。

没有拖更哈,这一期还是花费了不少力气的,如果哪里有误的地方还是希望大家指正,一起讨论,一起进步!
下一期的预告:C语言实现三子棋游戏,可以改成五子棋哦,有很详细的判断胜负的方法!
感谢观看,我们下一期再见!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1029126.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号