Tower Of Hanoi - 汉诺塔问题(C语言)

☆Welcome to House's blog!☆

本人主页:神王豪斯(重拾基础期)-CSDN博客

所属专栏:重拾C语言——神王降世的第一步!_神王豪斯(重拾基础期)的博客-CSDN博客

本文特点:内容详细且配有GIF图~

本人是一名不太聪明的计科专业学生,将会在这里记录我的学习进程,如果文章中有哪些地方说的不对或者代码有哪些可以改进的地方就有劳大家打在评论区啦!那咱们废话不多说,直接开始吧!

1.游戏规则

-有三根柱子(通常分别命名为 A、B、C)和若干大小不同的圆盘。

-最初,所有圆盘按照从大到小的顺序堆叠在一根柱子(比如 A 柱)上,大盘在下,小盘在上。

-目标是将 A 柱上的所有圆盘全部移动到另一根柱子(比如 C 柱)上。

-每次只能移动一个圆盘。

-并且在移动过程中,大盘不能放在小盘上面。

2.问题解析:

(GIF图来自博主十七ing,感谢ta为我们带来更美妙的观看体验!)

-只有一个环时,直接将其从A柱移到C柱即可;

-有两个环,我们就先把上面的小的移到B柱,再把下面大的环移到C柱,最后把B柱上的小环移到C柱上即可;

-有三个环,我们就只需...(深吸一口气)

把小的移到C,把中的移到B,把C上的小环移到B的中环上,这时候除了最底下的大环,其他两个环都按照大小暂时放在B柱上,C就空出来了,刚好把A上的大环移到C上

再把B最顶上的小环移到A上,把B上的中环移到C的大环上,最后再把A上的小环移到C的最顶上就搞定了...(气喘吁吁)

直接看动图吧...┓(;´_`)┏

从三个环的情况里面我们可以分析得到,一开始先将B柱作为中间柱,暂存小环与中环,在将大环安置好后,再将A柱作为中间柱,暂存小环,以此将中环移到C上,从而实现三个环从A向C的转移。

同理,当我们有n个环时,也可以先将B柱作为中间柱,用来安置(n-1)个环,将最下面最大的环移动到C柱,再将B柱上(n-1)个环以A柱为中间柱,转移到C柱上;当然在处理那(n-1)个环时,我们用一样的处理方法将其分成(n-1)个环中最底下的大环以及上面的(n-2)个环,以此类推......

看到这里,我相信绝世聪慧的你一定已经想到那四个字了——函数递归

3.代码实现

未解决这个问题我们可以定义两个函数:

第一个是 move 函数,用来打印移动环的过程

void move(char pos1, char pos2)
{
	printf("%c -> %c ", pos1, pos2);
}

第二个是 Hanoi 函数,用来递归移动环的过程

void Hanoi(int n,char A,char B,char C)
{
	if (n == 1)
	{
		move(A,C);
	}
	else {
		Hanoi(n - 1, A, C, B);
		move(A, C);
		Hanoi(n - 1, B, A, C);
	}
	
}

总代码如下:

#include<stdio.h>

void move(char pos1, char pos2)
{
	printf("%c -> %c ", pos1, pos2);
}

void Hanoi(int n,char A,char B,char C)
{
	if (n == 1)
	{
		move(A,C);
	}
	else {
		Hanoi(n - 1, A, C, B);
		move(A, C);
		Hanoi(n - 1, B, A, C);
	}
	
}

int main()
{
	int m = 0;

	scanf("%d", &m);

	Hanoi(m, 'A', 'B', 'C');

	return 0;
}

运行结果~

可以看到,在我们输入环的数量为3的时候,打印出的步骤与我们上面的分析是一摸一样滴~

4.注意事项

在处理递归函数调用问题时,我们不必陷入其中。因为计算机与人类思维不同,人类倾向做完一件事再做下一件,而计算机处理函数递归时,若上一级任务未完成,会先搁置(具体涉及函数栈帧内容,在后续的博客里会更新相关内容,点个关注敬请期待呀~),待下一级任务完成后再一级级往回传递结果。这使得研究其运行过程有些繁琐且混乱。

...

...

我说完了呀,你肿么还在看着我...你不会真的想让我把上面的函数调用过程搞出来吧┌(。Д。)┐!

要不说还是你了解我呢,具体运行过程就在下面,一起来看看吧~(*^▽^*)~

5.运行过程

下图中的H即为Hanoi函数

(整体顺序从左往右,蓝色框内的数字即为打印出来的顺序)

以上便是函数递归部分内容中的其中一道例题——汉诺塔问题,主要思想便是利用递归思想,将n环转化为1与(n-1)环,再对(n-1)继续进行递归操作,直到分解到1时执行挪动指令打印操作。

十分感激你看到这里,如果本篇内容对你有所启发的话就麻烦点个赞吧(虔诚脸),你的点赞、收藏、关注都是对我莫大的鼓励~

后续还会根据这篇内容更新有关递归经典题目——斐波那契数列以及青蛙跳台阶问题,敬请期待!

再次感谢你的观看,让我们下次再见!

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值