函数递归与汉诺塔

C初阶之函数递归

函数递归基本原理

什么是递归?程序调用自身的编程技巧称为递归recursion。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。其实递归主要就是压栈的过程。其递归的主要思想即:大事化小事
当然,递归也不是程序无限调用自身(会发生栈溢出),在使用递归时,必须满足两个必要条件:
1.存在限制条件,当满足这个限制条件后,递归便不在继续。
2.每次递归调用之后越来越接近这个限制条件(类似循环)。

通过例题来分析递归

递归的作用就是大事化小事

例题一:递归实现求n的阶乘

题目分析:
如果要求一个数的阶乘,比如求5的阶乘,就是5!=54321,这里要使用递归来实现,就必须推导出递归公式以及限制条件。
可以这样来想,5的阶乘可以表示为:
54!
5
43!
5
432!
54321!
54321
从以上的式子不难推导出递归公式:n!=n*(n-1)!
限制条件:当n==1时结束
根据分析可以写出代码

long long Fac(int N)//如果给的N很大,就不能用int类型来存放,所以在这使用long long类型
{
	if (N == 1)
		return 1;

	return N * Fac(N - 1) ;
}
int main()
{
	long long ret = Fac();
	printf("%d",ret);
	return 0;
}

图例分析
在这里插入图片描述
执行结果:
在这里插入图片描述
例题二:递归实现strlen的模拟(求字符串的长度)
题目分析:
要模拟实现strlen来求字符串的长度,可以使用函数的递归来做,大事化小事
比如说要求"hello"这个字符串的长度,可以这样想:
长度:1+("ello"的长度)
1+("llo"的长度)
1+("lo"的长度)
1+(“o"的长度)
1+(”/0"的长度)遇到 ‘\0’ 递归结束
在c语言中定义字符串用的是指针
char* str=“hello”
但是变量str指向的是字符串中第一个字符的地址,所以说每次递归后,str都要向后移动一位。
通过以上分析,可以得到该题的递归公式:1 + my_strlen(1 + str);
以及限制条件:*str==’\0’?
所以可以得到执行代码:

int my_strlen(char* str)
{
	if ('\0' == *str)
		return 0;
	else
		return 1 + my_strlen(1 + str);
}
int main()
{
	char* str = "hello";
	int ret=my_strlen(str);
	printf("%d",ret);

	return 0;
}

图例分析:
在这里插入图片描述

执行结果:
在这里插入图片描述

结语

递归是C语言中常用的一种执行方法,就是大事化小事简化代码。是以后编程的基础,也非常的重要,在以后的数据结构学习中也会使用递归(二叉树的递归),所以掌握递归是非常必要的

附加递归经典题型:汉诺塔

分析:
有三个平面A,B,C,现在有若干个(n个)盘子,得从A盘移动到C盘,问有要分多少次移动。
若n=1,可以直接从A移动到C,一次移动
若n=2,先把一个移动到B上,再把另一个移动到C上,再把小的移动到C上,共3次。
若n=3,根据以上规律可得,先把上面2个移动到B上(3次),再把最底下的移动到C上(1次),再把那2个通过A中转移动到C上(3次),共七次。
通过分析可以得到一下代码:

void move(char p1, char p2)//汉诺塔
{
	printf(" %c->%c ",p1,p2);//先定义一个移动函数
}
void han(int n, char p1, char p2, char p3)
{
	if (n < 2)
	{
		move(p1, p3);
	}
	else
	{
		han(n - 1, p1, p3,p2);
		move(p1, p3);
		han(n - 1, p2, p1, p3);
	}
	}

int main()
{
	han(1, 'A', 'B', 'C');
	printf("\n");
	han(2, 'A', 'B', 'C'); 
	printf("\n");
	han(3, 'A', 'B', 'C');
	
	return 0;
}

执行结果:
在这里插入图片描述

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值