【C】汉诺塔递归问题

汉诺塔的玩法是将一个木桩上的全部圆盘转移到另外一个木桩上

汉诺塔规则

  1. 一次只能移动一个圆盘
  2. 每个桩上只有最顶层的圆盘可以移动,并且所移动的圆盘只能移到空木桩上或者它要比木桩顶层已存在的圆盘小。也就是说,不能将大圆盘置于小圆盘之上。

问题

自定义一个函数,在给定汉诺塔层数以及以及需要操作的柱子名称后,能输出移动塔的方法


解决代码

常规代码:
/*解决思路*/
//起始柱[n层塔] 中间柱[空] 最终柱[空] 
//计划将一个n层的汉诺塔从[起始柱]全部移动到[最终柱]:
//STEP1:把除最低层外的所有层(共n-1层) -从[起始柱],借助[最终柱],放到[中间柱]
//STEP2:把最底层 -从[起始柱],放到[最终柱]
//STEP3:把除了最低层的(n-1)层 -从[中间柱],借助[起始柱],放到[最终柱]

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//创建一个函数,其本质功能是打印出 "'[起始柱]'->'[最终柱]'"
void hanoi(int n, char 起始, char 中间, char 最终)
{        //即打印出:【第二位参数】->【第四位参数】
	if (n == 1) //只有一层塔
	{    
		printf("%c -> %c\n",起始,最终);//直接打印【第二位参数】->【第四位参数】
	}
	else
	{
        //STEP1:[起始柱]->[中间柱]
		hanoi(n - 1,起始,最终,中间); //∴传参:[起始柱]-【第二位参数】,[中间柱]-【第四位参数】

        //STEP2:移动最底层
		printf("%c -> %c\n",起始,最终); //直接打印【第二位参数】->【第四位参数】

        //STEP3:[中间柱]->[最终柱]
		hanoi(n - 1,中间,起始,最终); //∴传参:[中间柱]-【第二位参数】,[最终柱]-【第四位参数】
	}
}
int main()
{
	printf("汉诺塔有几层?");
	int n = 0;
	scanf("%d", &n);
	hanoi(n,'A','B','C'); //给[起始柱] [中间柱] [最终柱] 分别传参命名为A、B、C
	return 0;
}
 带步骤编号代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int step = 0; //定义全局变量来显示汉诺塔移动步骤序号
int hanoi(int n, char a, char b, char c)
{
	if (1 == n)
	{
		step++;
		printf("step%d %c->%c\n", step, a, c);
	}
	else
	{
		hanoi(n - 1, a, c, b);
		step++;
		printf("step%d %c->%c\n", step, a, c);
		hanoi(n - 1, b, a, c);
	}
	return step;
}
int main()
{
	printf("汉诺塔有几层?");
	int n = 0;
	scanf("%d", &n);
	printf("共需要%d步\n", hanoi(n, 'A', 'B', 'C'));
	return 0;
}

最终效果:

 

写在最后:

递归的本质是大事化小,抽丝剥茧的解决复杂问题

因此,在编写递归代码时,最关键的是找到解决复杂问题的核心步骤。至于如何展开和调用这些步骤,则无需过分纠结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值