递归函数(详解+实战)

简介: 递归函数(详解+实战)

递归函数介绍

递归函数是指在函数的定义中调用函数本身的过程。递归函数可以用于解决那些可以通过将大问题拆分为更小的相似子问题来解决的情况。它通常包含两个关键部分:基本情况(递归终止条件)和递归调用。


基本情况(递归终止条件)是一个条件判断,当满足该条件时,递归函数不再调用自身,而是返回一个特定的值或执行特定的操作。这个基本情况用于避免递归无限进行,导致栈溢出错误。


递归调用是指在函数的定义中使用相同的函数来解决规模更小的子问题。通过不断地调用自身,并且每次调用时传递一个规模更小的子问题,递归函数最终会达到基本情况,从而逐步解决原始问题。


递归函数的设计需要满足以下要求:

  1. 定义明确的基本情况,确保递归函数可以终止。
  2. 在每次递归调用中,问题的规模都应该比原始问题减小,以便最终达到基本情况。
  3. 确保递归函数的每次调用都在不同的数据上进行操作,避免重复计算。

递归函数在解决许多问题时非常有用,如计算阶乘、斐波那契数列、二叉树遍历、图搜索等。它们可以提供一种简洁和直观的解决方案,并且在某些情况下比迭代方式更加简单和有效。

注意

使用递归容易产生栈溢出的错误

  • 递归一定要有出口,否则就是"死循环"的递归
  • 递归的次数不能太多

递归函数的作用

  1. 解决复杂问题:递归函数能够将一个复杂的问题分解为更小、更简单的子问题,从而使问题的解决变得更加直观和简单。
  2. 提高代码可读性:递归函数能够以一种自然而直观的方式描述问题的解决过程,使代码更易于理解和维护。
  3. 优化算法实现:某些问题的最优解往往可以通过递归函数来实现,例如分治算法、回溯算法等。递归函数可以帮助我们以更简洁的方式实现这些算法,提高代码的效率和可扩展性。
  4. 处理树形结构和递归数据结构:递归函数常用于处理树形结构、图等递归数据结构。例如,在树的遍历、搜索和构建等问题中,递归函数能够很好地表达和处理这些结构。
  5. 函数式编程:递归是函数式编程的重要概念之一,函数式编程强调使用函数来进行问题求解。递归函数是函数式编程中常用的工具,能够实现函数的组合和高阶函数的应用。

案例:实现10以内阶乘

def jie_cheng1(num:int) ->int:
  count = 1
  for i in range(1,num+1):
    count *=i
  return count
print(jie_cheng1(10))

递归思想

递归其主要思想在于:

  • 将问题分为规模更小的相同问题,持续分解,直到问题规模小到可以用非常简单直接的方式来解决
  • 分解完后,再合并结果

递归的编写

  • 定义 一个函数
  • 找到出口条件
  • 找到规律

 

 

def jie_cheng2(num:int):
  if num == 1:
    return 1
  else:
    return num * jie_cheng2(num-1)
print(jie_cheng2(10))

 

斐波那契数列(实战)

问题

有一对兔子,从出生第三个月起每个月都生一对兔子,小兔子长到第三个月后,每个月又生一只兔子,假如兔子都不死,问第二十个月的兔子对数为多少

斐波那契数列,又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”


斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89...


这个数列从第3项开始,每一项都等于前两项之和

循环实现

def fib1(n:int) -> int:
  if n <= 0:
    return 0
  elif n == 1 or n == 2:
    return 1
  a = b = 1
  rs = 2
  # 1 1 2 3
  for i in range(3,n):
    a = b
    b = rs
    rs = a + b
  return rs

递归实现

def fib2(n:int) -> int:
  if n <= 0:
    return 0
  elif n == 1 or n == 2:
    return 1
  else:
    return fib2(n-1) + fib2(n-2)
相关文章
|
缓存 Kubernetes 应用服务中间件
如何搭建代理镜像仓库
不知道各位有没有我这种尴尬:kubernetes搭建过程中需要拉取到一些镜像,比如: dockerhub的镜像,这个还好。毕竟有加速器。but k8s.gcr.io,quay.io.这些怎么搞?正巧搭建kubeadm 1.25,helm安装cilium的时候悲摧了。下载不动怎么搞?docker时代的时候我还可以直接导入,但是containerd时代了 导入了还是要麻烦一些阿?搜索引擎搜了一下,找到下面三个文章,借鉴一下!
|
存储 Cloud Native Linux
C++ deque底层原理
C++ deque底层原理
|
缓存 算法 调度
数据结构之 - 双端队列数据结构详解: 从基础到实现
数据结构之 - 双端队列数据结构详解: 从基础到实现
769 5
|
物联网 API 数据库
一文带你认识蓝牙 GATT 协议
正所谓磨刀不误砍柴工,我们有必要先深入的学习一下 GATT 以及 GATT 相关的一些知识。 本文我们就来了解一下 蓝牙 GATT 到底是什么?同时了解下我们使用的 ESP32-C3 GATT示例的工程的代码结构。
8740 5
一文带你认识蓝牙 GATT 协议
|
关系型数据库 数据库 PostgreSQL
PostgreSQL数据库的字符串拼接语法使用说明
【6月更文挑战第11天】PostgreSQL数据库的字符串拼接语法使用说明
1679 1
|
Linux Shell 网络安全
Docker中安装Centos7操作系统
Docker中安装Centos7操作系统
371 0
|
SQL 存储 缓存
《MySQL高级篇》八、索引优化与查询优化(二)
《MySQL高级篇》八、索引优化与查询优化
《MySQL高级篇》八、索引优化与查询优化(二)
|
存储 人工智能 编译器
【重学C++】【引用】一文看懂引用的本质与右值引用存在的意义
【重学C++】【引用】一文看懂引用的本质与右值引用存在的意义
542 0
|
存储 C语言 C++
C++中STL常用容器(vector、deque、list、map、set)一文带你了解
C++中STL常用容器(vector、deque、list、map、set)一文带你了解
717 0
|
移动开发 JavaScript C#
分享53戏源代码总有一个是你想要的(亲测每一个均可用)
分享53戏源代码总有一个是你想要的(亲测每一个均可用)
722 0