算法——递归
学习目标:
- 掌握算法入门知识
学习内容:
- 递归的定义
- 例题详细步骤讲解
1. 递归的定义
递归虽然每次调用的是相同的子程序,但它的参量、输入数据等均有变化,且随着调用的不断深入,必定会出现调用到某一层的函数时,不再执行递归调用而终止函数的执行。
输入输出以栈的形式存放。每调用一次进栈一次,当返回时执行出栈,把当前栈顶保留的值送回相应的参量中进行恢复,并按栈顶中的返回地址,从断点继续执行。
2. 例题详细步骤讲解
#include <stdio.h>
void fun(int n)
{
if (n<1) return;
else
{ printf("调用f(%d)前,n=%d\n",n-1,n);
fun(n-1);
printf("调用f(%d)后:n=%d\n",n-1,n);
}
}
在该例子中,n<1即递归出口。
-
当n=5时,分析下整个递归过程:
(1)n>1,输出 “调用f(4)前,n=5” ,递归开始,执行fun(4)
(2)n>1,输出“调用f(3)前,n=4”,递归开始,执行fun(3)
(3)n>1,输出“调用f(2)前,n=3”,递归开始,执行fun(2)
(4)n>1,输出“调用f(1)前,n=2”,递归开始,执行fun(1)
(5)n>1,输出“调用f(0)前,n=1”,递归开始,执行fun(0)
(6)n<1,return;
(7)此时fun(0)调用完毕,从断点处继续向下执行,输出“调用f(0)后,n=1”
(8)此时fun(1)调用完毕,从断点处继续向下执行,输出“调用f(1)后,n=2”
(9)此时fun(2)调用完毕,从断点处继续向下执行,输出“调用f(2)后,n=3”
(10)此时fun(3)调用完毕,从断点处继续向下执行,输出“调用f(3)后,n=4”
(11)此时fun(4)调用完毕,从断点处继续向下执行,输出“调用f(4)后,n=5” -
时间复杂度:
如果 n < 1,函数立即返回,不执行任何打印操作。
如果 n >= 1,函数首先打印一条消息,然后递归调用自身 fun(n-1),最后再打印另一条消息。
由于每次递归调用都会使 n 减少 1,直到 n < 1 为止,因此递归调用的深度是n。因此,时间复杂度是 O(n)。 -
空间复杂度:
主要考虑的是递归调用栈的使用。每次递归调用都会将当前函数的状态(包括参数、局部变量和返回地址)压入调用栈。递归调用的深度是 n,因此调用栈中最多将有 n 个函数帧,每个函数帧占用的空间是常数。因此,空间复杂度是 O(n)。