递归调用与时间复杂度的学习总结

本文介绍了递归函数的应用及其实现方式,并对比了递归与循环的时间复杂度。此外,还详细解释了一段用于判断素数的代码,分析其功能及时间复杂度。

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

今天主要学习了两个知识点。分别是递归调用和时间复杂度。重点是时间复杂度,比较复杂奋斗

1. 递归函数

1.1题目1:

一共5个人,一个比一个大2岁,最后一个10岁,问第一个多少岁?
首先用循环形式来写函数,如下:
int Age1(int n)//O(n)
{
	int tmp = 10;
	for(int i=1;i<n;i++)
	{
		tmp += 2;
	}
	return tmp;
}

而用递归函数如下:

int Age(int n)   //O(n)
{
	int tmp;
	if(n == 1)//边界条件
	{
		tmp = 10;
	}
	else
	{
		tmp = Age(n-1) + 2;
	}
	return tmp;
}

但是递归函数的时间复杂度是比循环大的。

2.时间复杂度

如下一段程序:
bool Fun(int n)
{
     int i=2;
    while((n%i)!=0 && i*1.0<sqrt(n))
    {
          i++;
    }
    if(i*1.0>sqrt(n))
       return true;
    else
       return false;
}
现在问:1.这段程序实现什么功能?  2.时间复杂度是多少?
答:1.判断一个数是否为素数。
        2.时间复杂度为sqrt(n)。
### 时间复杂度分析 斐波那契数列的递归实现是基于其数学定义,即 $ f(n) = f(n-1) + f(n-2) $,其中 $ f(0) = 0 $ 和 $ f(1) = 1 $ 是初始条件。该递归实现的时间复杂度可以通过递归树法进行分析。 在递归过程中,每次调用 $ f(n) $ 都会进一步调用 $ f(n-1) $ 和 $ f(n-2) $,直到递归终止条件 $ f(0) $ 或 $ f(1) $ 被触发。递归树的根节点为 $ f(n) $,它有两个子节点 $ f(n-1) $ 和 $ f(n-2) $。节点 $ f(n-1) $ 又会分裂为 $ f(n-2) $ 和 $ f(n-3) $,以此类推。递归树的叶子节点是 $ f(0) $ 和 $ f(1) $,它们分别返回 0 和 1。 递归树的深度为 $ n $,每一层的节点数量和该层的计算量决定了整体的时间复杂度。由于每个节点的计算都涉及到两个子节点的递归调用,因此递归树的节点总数接近 $ 2^n $,导致时间复杂度为 $ O(2^n) $ [^1]。 ### 代码示例 以下是斐波那契数列的递归实现代码: ```c #include <stdio.h> int f(int n) { int ret; if (n == 0) ret = 0; else if (n == 1) ret = 1; else ret = f(n-1) + f(n-2); return ret; } int main(int argc, char const *argv[]) { int n; scanf("%d", &n); printf("f(n)=%d\n", f(n)); return 0; } ``` ### 优化建议 由于递归实现的时间复杂度为 $ O(2^n) $,它在实际应用中效率较低。为了提高性能,可以采用非递归方法,其时间复杂度为 $ O(n) $。非递归方法通过迭代计算斐波那契数列,避免了递归带来的重复计算和栈溢出风险。 以下是斐波那契数列的非递归实现代码: ```c #include <stdio.h> int main(int argc, char const *argv[]) { int n; scanf("%d", &n); int ans; if (n == 0) ans = 0; else if (n == 1) ans = 1; else { int a = 0, b = 1; for (int i = 2; i <= n; i++) { ans = a + b; a = b; b = ans; } } printf("f(n)=%d\n", ans); return 0; } ``` ### 空间复杂度分析 递归实现的空间复杂度主要由递归调用栈的深度决定。每次递归调用 $ f(n) $ 都会在内存栈中分配空间以保存参数、返回地址及临时变量。因此,递归实现的空间复杂度为 $ O(n) $,而循环实现的空间复杂度为 $ O(1) $ [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值