数据结构与算法—递归recursion

目录

递归需要满足的三个条件

编程要点

递归复杂度

算法使用注意点

实例分析


递归需要满足的三个条件

1、一个问题需要分解为几个子问题的解

2、这个问题与分解之后的子问题,除了数据量不同,求解思路一样

3、终止条件

编程要点

        写出递推公式

        找到终止条件

        特殊条件检查

递归复杂度

在时间复杂度 O(n^2)

        递归,函数调用的数量较大时,非常耗时。

空间复杂度 O(n)

        递归调用一次就会在内存栈中保存一次现场数据,在分析递归代码空间复杂度时,需要额外考虑这部分开销。

算法使用注意点

1、警惕堆栈溢出

        函数调用会使用栈来保存临时变量,每调用一个函数,都会将临时变量封装为栈帧压如内存栈。系统栈空间一般都不大,递归层次很深,有堆栈溢出风险。最大深度比较小,如10,50,这样,否则警惕使用递归。因为当前线程剩余的栈空间大小事先无法计算,如果实时计算,代码过于复杂,影响可读性。

2、警惕重复计算

        现象,在递归实现时,如f(6) = f(5)+f(4);f(5)=f(4)+f(3),这样f(4)两次计算

        避免重复计算,可以使用一个数据结构(如散列表)来保存已经求解过的f(k),当递归遇到f(k)时,先看是否已经求解过了,避免重复计算。

实例分析

爬楼梯,一次可以上两个台阶,也可以上一个台阶。10个台阶有多少中方法?

公式:
f(n) = f(n-1)+f(n-2);条件 f(0) = 0,f(1) = 1,f(2) = 2

fun()函数,重复条件判断;fun1()没有使用重复条件

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


int fun(int n,int *value)
{
	if(value[n]!=0)
	{
		return value[n];
	}
	value[n] = fun(n-1,value) + fun(n-2,value);
	return value[n];
}

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

void main()
{
	int n = 4;
	int ret = 0;
	printf("#############fun1#######\n");
	ret = fun1(n);
	printf("res1=%d\n",ret);
	
	printf("#############fun2#######\n");
	int *value = (int *)malloc(sizeof(int)*(n+1));
	if(value == NULL)
	{
		return;
	}


	memset(value,0,sizeof(int)*(n+1));
	value[0] = 0;
	value[1] = 1;
	value[2] = 2;

	ret = fun(n,value);

	printf("res=%d\n",ret);

	free(value);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

为了维护世界和平_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值