C语言函数递归—经典递归问题

目录

一.什么是递归?

二. 汉诺塔问题

2.1 认识什么是汉诺塔

2.2 汉诺塔打印步数

 2.3 汉诺塔打印步骤

三.青蛙跳台阶问题 


一.什么是递归?

这里我们先简单的认识一下什么是函数递归:我们可以理解为在一个过程或函数在其定义或说明中直接或间接调用自身的的一个技巧我们称为函数递归。

递归的主要策略:就是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归的主要的思考方式:就是把大事化小

递归可以看成是两个部分:一个是递推,一个是回归

递归的两个必要条件:

1.存在限制条件,当满足这个限制条件的时候,递归便不再继续

2.每次递归调用之后越来越接近这个限制条

 在简单的认识了递归后,就让我们一起来学习一下函数递归的一些经典问题。

二. 汉诺塔问题

2.1 认识什么是汉诺塔

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

2.2 汉诺塔打印步数

目的:用递归的方式计算一个n层的汉诺塔从A柱到C柱所需要的步数。

规律:经过例表我们可以发现n层塔所需要的步数就是2的n次方-1。

C语言函数递归—经典递归问题_第1张图片 

 如何用递归来表示呢?

我们可以表示为:2*f(n-1)+1 的一个递推式(up因懒惰未做解释,见谅^-^)

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int Hanio_steps(int num)
{
	if (num == 1)
		return 1;
	else
		return 2 * Hanio_steps(num - 1) + 1;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Hanio_steps(n);
	printf("%d\n", ret);
	return 0;
}

 2.3 汉诺塔打印步骤

前面我们已经知道了n层汉诺塔的步数,那n层汉诺塔 是如何从A柱移动到C柱呢?让我们一起来寻找一下规律。在移动的过程中,保证小圆盘再大圆盘的上面。

当只有一个圆盘的时候,直接将圆盘从A柱移动到C柱  A->C

C语言函数递归—经典递归问题_第2张图片

 当有两个圆盘的时候,我们需要先把一个圆盘移到B柱,然后把2盘子移到到C柱,再把B柱上的1盘子移动到C柱。  A->B,A->C,B->C

C语言函数递归—经典递归问题_第3张图片

现在假设我们有n个圆盘,既n>=2,这个时候我们把n-1看成一个整体,这样就是第n-1个圆盘和第n个圆盘。规律如下:

1.首先,我们把n-1这一堆圆盘借助C柱放到B柱上.  A->C,C->B

2.再把最大的圆盘放到C柱中。 A->C

3.最后我们再把n-1这一堆圆盘借助A柱放到C柱上 。 B->A,A->C

C语言函数递归—经典递归问题_第4张图片 

思路整理:

当n==1时,直接将盘子从A移动到C

当n>1时,我们可以拆分成三个步骤:

1.先将n-1个盘子从A移到B中

2.再将编号为n的盘子从A移动到C中

3.最后将n-1个盘子从B移到C中

再这个过程中我们会发现1.3就是在进行一个递归

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include

Hanio_process(int n, char a,char b,char c)
{
	if (n == 1)
	{
		printf("%c->%c\n", a, c);
	}
	else
	{
    //  n-1的圆盘从A柱移到B柱
		Hanio_process(n - 1, a,c,b);
	//  将n层圆盘从A柱移动到C柱
		printf("%c->%c\n", a, c);
	//  再将n-1的圆盘从B柱移动到C柱
		Hanio_process(n - 1, b, a, c);
	}
}

int main()
{
	int n = 0;
	printf("请输入层数:");
	scanf("%d", &n);
	Hanio_process(n,'A','B','C');
	return 0;
}

 C语言函数递归—经典递归问题_第5张图片

三.青蛙跳台阶问题 

问题详细:一只青蛙一次最少跳一个台阶,一次最多跳两个台阶,求:青蛙跳上第n层台阶的时候有多少种跳法。

问题分析:

一层台阶:1种跳法

二层台阶:2种跳法

三层台阶:3种跳法

四层台阶:5种跳法

……

如果我们这里列一个数列:

1 2 3 5 8 13 21 34  55…

这个时候我们就会发现该数列由1和2开始,后面的每一项的数都是前面两项数字的和。

这时候是不是会发现有那熟悉的味道了,没错这个青蛙跳台阶的问题就是一个隐藏的

斐波那契数列问题。

规律:

F(1)=1,F(2)=2

当n>=3时,F(n)=F(n-1)+F(n-2) 

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int Jump_method(int n)
{
	if (n ==1)
	{
		return 1;
	}
	else if (n == 2)
	{
		return 2;
	}
	else
	{
		return Jump_method(n - 1) + Jump_method(n - 2);
	}
}

int main()
{
	int n = 0;
	printf("输入台阶层数:");
	scanf("%d", &n);
	int ret=Jump_method(n);
	printf("共有%d种跳法\n",ret);
	return 0;
}

 

 后文:

看了一下午才理解汉诺塔这个问题,也参考了很多优秀大佬的解释,在此非常感谢各位大佬的优秀好文。

你可能感兴趣的:(c语言,c++)