任务五:递归

本文深入探讨了递归算法的基本原理,包括其定义、关键特性及应用案例。通过具体的编程实例,如HDU爬楼梯问题和LeetCode的题目解析,展示了递归算法在解决复杂问题时的效率和简洁性。同时,文章还讨论了递归算法的局限性和优化方法,如避免栈溢出和使用非递归替代方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归思想

是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象。在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知。使用递归解决问题,思路清晰,代码少。但是在主流高级语言中(如C语言、Pascal语言等)使用递归算法要耗用更多的栈空间,所以在堆栈尺寸受限制时(如嵌入式系统或者内核态编程),应避免采用。所有的递归算法都可以改写成与之等价的非递归算法

1. 子问题须与原始问题为同样的事,且更为简单;

2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。

一个题目:HDU爬楼梯

有一个楼梯共m阶,刚开始时你在第一阶,若每次只能跨上一级或两级,要走上M级共有多少种走法?

第一种方法:递归法

#include<stdio.h>
int fn(int n)
{
	if (n == 1 || n == 2)
	{
		return 1;
	}
	if (n > 2)
	{
		return fn(n - 1) + fn(n - 2);
	}
}
int main()
{
	int n, i, m;
	while(scanf_s("%d", &n)!=EOF)
	for (i = 0; i < n; i++)
	{
		scanf_s("%d", &m);
		printf("%d\n", fn(m));
	}
	return 0;
}

因为HDU上无法AC,即当n过大时会导致时间长度大于1000ms.无法通过。

#include<stdio.h>
typedef unsigned long long ULL;
#define N 40
ULL stairs[N + 1];
void setstairs(int n)
{
	ULL s1=1, s2=1, temp;
	stairs[0] = 0;
	stairs[1] = 1;
	stairs[2] = 1;
	for (int i = 3; i <= n; i++)
	{
		temp = s1 + s2;
		s1 = s2;
		s2 = temp;
		stairs[i] = s2;
	}

}
int main()
{
	int m, i, n;
	setstairs(N);//打表
	while (scanf_s("%d", &m) != EOF)
	{
		for (int i = 0; i < m; i++)
		{
			scanf_s("%d", &n);
			printf("%lld\n", stairs[n]);
		}

	}
	return 0;
}

LeetCode题解

题目

考虑:这个题的难点在于处理各种极端输入,例如指数为0,指数为负等,需要考虑全面。在实现乘方的过程中,使用递推关系式减小乘法次数,缩短运行时间。题的难点主要是在边界条件:如果 n < 0,是不是 n = -n, x = 1 / x ,再进行递归就能解决了呢?如果 n = Intege.MIN_VALUE,n = -n 会出现溢出,怎么办呢?我们可以先将 n / 2 赋值给 t,再将 t = -n,就不会出现溢出问题。(static int MAX_VALUE 值为 231-1 的常量,它表示 int 类型能够表示的最大值。 
           static int MIN_VALUE 值为 -231 的常量,它表示 int 类型能够表示的最小值。 )
由我们对递推的了解可知它是每一次都需调用这个函数,那么我们需要了解这个函数的规律。


 

第一次实现

double myPow(double x, int n) {
 return pow(x,n);
}

 

第二次实现

 

double myPow(double x, int n) {
    if(n==0)  return 1;
    if(n==1)  return x;
    if(x==0)  return 1;
     int t=n/2;
    if(n<0)
    {
         t=-t;
        x=1.0/x;
    }
    double ret=myPow(x,t);
    if(n%2==0)
        return ret*ret;
    else
        return ret*ret*x;
}

 

第三次实现

double myPow(double x, int n) {
    if(n==0)  return 1;
     int t=n/2;
    if(n<0)
    {
         t=-t;
        x=1.0/x;
    }
    double ret=myPow(x,t);
    if(n%2==0)
        return ret*ret;
    else
        return ret*ret*x;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值