用最通俗的文字,讲最通俗的递归

递归入门

1.递归概论及最简单递归实现

a.递归能解决什么问题

  • 递归能够解决循环的所有问题,但是,循环不一定能解决递归的问题。

b.递归解释

  • 首先声明,我对递推的看法完全是像数列中的递推公式的一个东西,而不是正统的先逆后顺的思想。如有不完善之处还请各位指正。

  • 递归就像是一个数列的递推公式: f ( x ) = k ∗ f ( x − 1 ) + b f(x)=k*f(x-1)+b f(x)=kf(x1)+b(不过我没有考证过是不是这个原因才叫递归)

    所以从这里可以看出,基本上循环的内容,你写个递归的函数都能做出来。

c.代码实现

i.构成:
  • 从数列的启发中,你可以很容易看到,所有的递归式子必须要有一个首项递推关系

  • 在递归里面也有这样的概念,不过我们把首项叫做出口,把递推关系叫做关系

  • 出口:就是使变量停止变化的位置。不过请注意我对出口的解释中,有一层数字从大到小的含义。换句话说,就是数列中的首项一般是从小到大进行计算,而递归里面的数字是从大到小依次排列。在最小点实现循环的停止。(这段文字有点长,不想看也罢,反正一会儿会上代码)

  • 关系:当然就是递推关系了。

  • 从数学到代码(划重点):

    数学公式中的 f ( x ) = k ∗ f ( x − 1 ) + b f(x)=k*f(x-1)+b f(x)=kf(x1)+b等价于代码中的

    return k*f(n-1)+b;
    
ii.举例分析:

斐波那契数列的实现

  • 按照数学方法,应该写成首项 f ( 1 ) = a , f ( 2 ) = b f(1)=a,f(2)=b f(1)=a,f(2)=b递推关系 f ( x ) = f ( x − 1 ) + f ( x − 2 ) f(x)=f(x-1)+f(x-2) f(x)=f(x1)+f(x2)。这样就能得出第N项的值了。

  • 按照C语言,应该写成

    int f(int n)
    {
    	if(n==1)					//理解下“出口”的含义(这个里面不能打高亮)
    	return 1;
    	else if(n==2)				//出口2
    	return 1; 
    	else 						//实现递推
    	return f(n-1)+f(n-2);
    }
    
    • 通过这个好好理解下递推中的逆推思想。
iii.疑难解答(此部分为个人思考,如有错误还请指正):
  • 有的好奇宝宝会问:为什么不正着推而反着推?
  • 在我看来,正着推的话,要多加一个变量,而反着推,则会省略这一步冗杂项。
  • PS:此疑难解答仅限于此文我的递推思想,如果是正统 先逆后顺的思想的话,请自动忽略此部分。
iv.附录:
斐波那契数列的实现:
#include <stdio.h>
int f(int n)							//斐波那契数列的递推表示
{
	if(n==1)
	{
	return 1;
}
	else if(n==2)
	{
		return 1; 
	}
	else 
	return f(n-1)+f(n-2);
}
int main()
{
	int n;
	scanf("%d",&n);						//输入你想要求的轮数(兔子生几轮)
	printf("%d",f(n));
	return 0;
}
友情提示,冒泡法也可以用递归式子写出
  • 仔细思考,随后给出答案。

2.递归与数组

a.基础奠基:

  • 数组指针是指向数组首元素的地址的指针,其本质为指针(这个指针存放的是数组首地址的地址,相当于2级指针,这个指针不可移动)。

b.代码实现

求一个数组中前N项和

int sum(int arr[],int n)
{
	if(n==0)
	return arr[0];
	else
	return sum(arr,n-1)+arr[n];
}

实际上,就是将基础奠基里面的内容加入进去就行了,因此我就不再写注释了。

3.总结及习题练习:

a.总结:

  • 在这个里面,第一步要做的是确定关系,就是把最后一项和前面几项分成两部分。例如上个代码,就是将前几项sum(arr,n-1)和最后一项arr[n]分离出来,进行关系处理(比如比较大小,求和等)。
	return sum(arr,n-1)+arr[n];
  • 那么,第二步要做的是确定出口,确定出口条件输出结果 。例如上个代码,就是将第一项的结果列了出来。
	if(n==0)
	return arr[0];
  • 因此,你要明白:递归就是找到出口关系,再利用你高中打下的数学基础,把递归解释或写清楚!

b.习题练习:

i.比较一个数组内元素的大小
  • 代码分析:

    出口:就是输出条件(if)和输出结果(return)。

	if(n==0)
        return a[0];
  • 关系:把最后一项(a[n])和除最后一项外的所有项(max(a,n-1))进行关系处理(比大小)
  • PS:从下面的代码也可看出,关系处理也是输出条件和输出结果的复合体。
if(max(arr,n-1)>arr[n])
    return max(arr,n-1);
else
    return a[n];

最重要的:
没事别用递归!!!

更多习题请看

注释:在看上面链接的时候,摁住ctrl点击超链接就行。
————————————————————————————————————————
高山仰止,景行行止,虽不能至,然心向往之。
——《诗经·小雅》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值