递归的理解与应用(详细)(下)

简介: 递归的理解与应用(详细)(下)

三. 函数递归典型例题的实现

这里在写几道题巩固理解💪

3.1 🥰求n的阶乘

3.1.1题目描述

用递归的方法求n的阶乘(不考虑溢出问题)
例如:
输入:4,输出 24

3.1.2解题思想

n的阶乘为1234…(n-1)n,我们可以先用递推的思想,先算出n(n-1)的值,再用n(n-1)的值乘以(n-2),这样依次乘下去,以n=1为限制条件,返回1。然后再用回归思想,返回回去,及可得到n的阶乘。

3.1.3代码实现

#include<stdio.h>
int factorial(int n)
{
  if (n == 1)
    return 1;
  else
    return n * factorial(n - 1);        
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int ret = factorial(n);
  printf("n的阶乘为:%d", ret);
  return 0;
}

3.1.4执行结果

3.1.4递归流程图

3.2👉strlen函数的模拟实现

3.2.1题目描述:

用递归的方法模拟实现strlen函数
例如:
输入:abc,输出 3

3.2.2 解题思想

strlen函数遇到 ’\0’才会停止,所以我们以 ’\0’为限制条件,我们每调用一次我们自己实现的my_strlen函数,次数就加一,直到遇到 ’\0’停止。

3.2.3 代码实现

int my_strlen(char* str)
{
  if (*str != '\0')
  {
    return 1 + my_strlen(str + 1); //str是数组的首地址
  }
  return 0;
}
int main()
{
  char a[] = "abcdefg";
  int ret = my_strlen(a);
  printf("%d", ret);
  return 0;
}

3.2.4执行结果

3.3🍒求n的k次幂

3.3.1题目描述

用递归的方法实现n的k次幂
例如:
输入:3,3,输出 27

3.3.2解题思路

解题思路:以k>0和k=0为限制条件,每一次递推就乘以n,并且k都减一次1,直到不满足限定条件,然后回归,即为27。

3.3.3代码

#include<stdio.h>
int power(int n, int k)
{
  if (k > 1)
  {
    return power(n, k - 1) * n;
  }
  else
    return n;
}
int main()
{
  int n = 0;
  int k = 0;
  scanf("%d", &n);
  scanf("%d", &k);
  int ret = power(n, k);
  printf("%d ", ret);
  return 0;
}

3.3.4执行结果

3.5🍒斐波那契数📌

3.5.1 题目描述

计算斐波那契数递归实现求第n个斐波那契数
例如:输入:5 输出:5
输入:10, 输出:55

3.5.1 解题思路

斐波那系数是前两项加起来等于后一项:1,1,2,3,5,8,13…,所以我们可以以n<=2为限制条件,当n=1或2时,返回1,然后到n=3项时就是n=1项和n=2项之和,然后依次往后推,即Fib(n)就是Fib(n-1)和Fib(n-2)之和。

3.5.2.1非递归求解

#include<stdio.h>
int fac(int n) {
  int a=1, b=1, res=0;
  if (n == 1 || n == 2) {
    return 1;
  }
  else {
    for (int i = 3; i <= n; i++) {
      res = a + b;
      a = b;
      b = res;
    }
  }
  return res;
}
int main() {
  int n;
  scanf("%d", &n);
  printf("%d",fac(n));
  return 0;
}

3.5.2.2执行结果

3.5.3.1递归求解

#include<stdio.h>
int fac(int n) {//斐波那契非递归
  int a=1, b=1, res=0;
  if (n == 1 || n == 2) {
    return 1;
  }
  else {
    return fac(n - 1) + fac(n - 2); 
  }
}
int main() {
  int n;
  scanf("%d", &n);
  printf("%d",fac(n));
  return 0;
}

3.5.3.2执行结果

🍭斐波那契数的非递归的实现优于递归实现的原因

1.因为每一次函数递归(函数调用)都会在函数栈帧上开辟一块空间,所谓的压栈。这样会大大降低我们代码的执行效率。

2用递归法实现的斐波那契数正对应了其缺点,因为它的递推时会有很多分支,一个分支下面又有很多分支,每一个小分支都是函数的调用,然而还有回归,函数栈帧需要销毁,这会大大降低代码的执行效率,如果n=50,则代码执行时间都要1个多小时,所以用递归法实现的斐波那系数其实是不实用的。

3.而用非递归的方法实现,可以大大提高代码的运行效率。只是每一次循环,n1,n2,tmp会被赋值,代码执行次数大大减少,所以斐波那契数的非递归的实现优于递归实现的。


相关文章
|
5月前
|
算法 数据库
递归最佳解析
递归最佳解析
65 0
|
2月前
|
算法
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
|
4月前
|
C语言
C语言函数递归详解:理解递归的原理与应用
C语言函数递归详解:理解递归的原理与应用
69 0
|
5月前
|
机器学习/深度学习 编译器 C语言
关于函数递归的基础
关于函数递归的基础
49 5
|
5月前
【每日一题Day286】LC21合并两个有序链表 | 链表模拟 递归
【每日一题Day286】LC21合并两个有序链表 | 链表模拟 递归
29 0
|
5月前
|
算法 Java Serverless
【Java递归】一篇文章带你了解,什么是递归 ,递归的特点,递归应用场景,递归练习题
【Java递归】一篇文章带你了解,什么是递归 ,递归的特点,递归应用场景,递归练习题
111 0
糊里糊涂的递归和递归经典题(下)
糊里糊涂的递归和递归经典题(下)
|
算法 C语言
糊里糊涂的递归和递归经典题(上)
糊里糊涂的递归和递归经典题
认识了解递归的原理,学会递归的运用
认识了解递归的原理,学会递归的运用