汉诺塔(函数递归)

前言
汉诺塔问题是一个经典的数学谜题,也是函数递归的一个经典问题,起源于印度。问题的设定是有三个柱子,第一个柱子上有一组不同大小的圆盘,按照从上到下依次变大的顺序摆放。目标是将所有的圆盘从第一个柱子移动到第三个柱子上,但是在移动过程中必须遵守以下规则:
1,每次只能移动一个圆盘。
2,每次移动时,只能将一个圆盘从柱子的顶端移到另一个柱子的顶端。
3,不允许将大圆盘放在小圆盘的上面。
在了解了规则之后我们该怎么样用函数递归的方式解决它呢?那么话不多说我们现在开始。
在这里插入图片描述
函数递归讲究一种由大化小的思想。
首先我们要定义一个函数hanoi(int n,char pos1 ,char pos2 ,char pos3)
首先n代表有n个盘子,pos1是起始位置,pos2是中转位置,pos3是目的位置。
然后我们在定义一个move函数move(char pos1,char pos2)将pos1的盘子移动到pos2上我们先写一下简单的move函数

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

在这里插入图片描述
如图分别有三个柱子a,b,c,我们的目的是将a上的n个盘子移动到c上。当n=1时我们可以直接将盘子从a移到c。所以我们先这样写。

void hanoi(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
	
	}
}

当n不等于1时,我们的主要思想是现将a上的n-1个盘子移动到b上,然后将a上剩余的一个盘子移动到c上。如图。
在这里插入图片描述
那么此时我们要把n-1个盘子从a移动到b,即起始位置是a,目的位置自然是b,那c就是我们的中转位置。那么我们开始写代码。

void hanoi(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
	hanoi(n-1,pos1,pos3,pos2);//此时pos2是目的位置,pos1是起始位置
	move(pos1,pos3);//将a上的那一个放到c上
	}
}

接下来我们需要把b上的n-1个放到c上,此时我们的b就是起始位置,c是目的位置,而a就是中转位置。如图所示。
在这里插入图片描述
到这里我们发现就完成了任务那么我们再写一下代码。

void hanoi(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
	hanoi(n-1,pos1,pos3,pos2);//此时pos2是目的位置,pos1是起始位置
	move(pos1,pos3);//将a上的那一个放到c上
	hanoi(n-1,pos2,pos1,pos3);//此时pos2是起始位置,pos3是目的位置
	}
}

这样我们的hanoi函数就写好了下面我们来演示。

#include<stdio.h>
void move(char x, char y)
{
	printf("%c -> %c ", x, y);
}
void hanoi(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
		hanoi(n - 1, pos1, pos3, pos2);//此时pos2是目的位置,pos1是起始位置
		move(pos1, pos3);//将a上的那一个放到c上
		hanoi(n - 1, pos2, pos1, pos3);//此时pos2是起始位置,pos3是目的位置
	}
}
int main()
{
	int n;
	scanf("%d", &n);//输入共有n个盘子
	char a = 'A', b = 'B', c = 'C';
	hanoi(n,a,b,c);
	return 0;
}

输入n=4时结果是这样的
在这里插入图片描述

尾声
关于函数递归经典问题汉诺塔的分享就到这里,如果觉得博主讲的不错请给博主一个赞和收藏鼓励一下博主,关注博主不迷路,我们下期再见!

  • 61
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 60
    评论
评论 60
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小马的Trainer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值