python—递归函数

递归函数

定义:即在函数定义中自己调用自己

  • 递归就是在过程或函数中自我调用
  • 递归必须有递归出口,即递归结束条件


举个栗子—阶乘:

def fact(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
# 120

函数执行过程:

===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

注意: 使用递归函数需要防止栈溢出。 函数调用是通过 栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会增加一层栈帧,每当函数返回,就会减一层栈帧。由于栈的空间是有限的,递归调用次数过多就会导致栈溢出


尾递归优化:

为了避免栈溢出,可以通过尾递归优化,尾递归实际与循环一样,我们可以循环当做是特殊的尾递归.

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况

# 尾递归的例子
def calc(n):
    print(n - 1)
    if n > -50:
        return calc(n-1)

根据尾递归定义,我们的阶乘就不是尾递归了

def fact(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)

因为返回语句是一个乘法操作 ,return n * factorial(n - 1) 引入了乘法操作。

  • 尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出 .
  • 使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
  • 针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
  • Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。^_^

汉诺塔问题

汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

def move(n,a,b,c):
    if n == 1:
        print(‘move‘, a, ‘-->‘, c)
    else:
        move(n-1,a,c,b)
        move(1,a,b,c)
        move(n-1,b,a,c)

move(3,‘A‘,‘B‘,‘C‘)
# 打印结果:
# move A --> C
# move A --> B
# move C --> B
# move A --> C
# move B --> A
# move B --> C
# move A --> C

原文地址:https://www.cnblogs.com/friday69/p/9235242.html

时间: 2024-10-11 13:46:37

python—递归函数的相关文章

Python 递归函数 详解

Python 递归函数 详解   在函数内调用当前函数本身的函数就是递归函数   下面是一个递归函数的实例: 第一次接触递归函数的人,都会被它调用本身而搞得晕头转向,而且看上面的函数调用,得到的结果会是: 为什么会得出上面的结果呢?因为都把调用函数本身之后的代码给忘记了,就是else之后的python 代码. 实际此递归函数输出的是以下结果: 相信大家看到这里都有点蒙,小编也一样,我第一次看到这个递归函数时,只能理解到第一个结果.那是因为,大部分人在做事情的时候,中断第一件事,被安排去做第二件事

python递归函数(10)

一个函数在函数体内部调用自己,这样的函数称为递归函数,递归的次数在python是有限制的,默认递归次数是997次,超过997次会报错:RecursionError. 一.递归函数案例 案例一:计算数字N的阶乘(举个栗子:9的阶乘 = 9*8*7*6*5*4*3*2*1) # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解忧 @Blog(个人博客地址): shuopython.com @WeChat Offi

python递归函数下不能正常使用yield

# -*- coding:utf-8 -*- import os import time file_list = [] def findFile(path): listFile = os.listdir(path) for file in listFile: try: file =os.path.join(path,file) if os.path.isfile(file): yield file # test1 #file_list.append(file) # test2 #print(fi

python递归函数

1.递归函数:简单点说就是自己调用自己,递归函数必须有一个明确的结束条件,python中默认的最大递归次数为999次,其目的是保护资源不被耗尽 2.每次进入更深一层次递归时,问题规格相经上次递归都应有所减少 3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈这种数据结构实现的,每当进入一个函数调用时,会增加一个栈帧,每当函数返回时,就会减少一个栈帧,由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出)

Python递归函数与匿名函数

递归函数 Python对递归的深度有限制,超过即会报错.所以一定一要注意跳出条件. #斐波拉契数列 #一个数列,第一个数是1,第二个数也是1,从第三个数开始,每一个数是前两个数之和 #公式:f(1) =1, f(2) = 1, f(3) = f(1) + f(2), ..., f(n) = f(n-2) + f(n-1) #例如:1, 2, 3, 5, 8, 13, 21... def fib(n): if n == 1: return 1 elif n == 2: return 1 else:

python递归函数及二分法查找

函数的递归: 在一个函数的内部调用自己 死循环: 可以无限循环,不会停止 while True: print('我不是递归') 递归: 不是死循环,有最大循环深度 def story(): print('我是递归') story() story() 超过了递归的最大深度报错 RecursionError: maximum recursion depth exceeded while calling a Python object 官网上 源码中设置的递归深度: 1000自己实际测试递归深度: 9

Python递归函数如何写?正确的Python递归函数用法!

在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.一.举个例子,我们来计算阶乘n! = 1 x 2 x 3 x … x n,用函数fact(n)表示,可以看出:fact(n) = n! = 1 x 2 x 3 x … x (n-1) x n = (n-1)! x n = fact(n-1) x n所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理.ps:另外很多人在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致

Python递归函数与斐波那契数列

定义:在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 阶乘实例 1 n = int(input(">>:")) 2 3 4 def f(n): 5 s = 1 6 for i in range(2, (n + 1)): 7 s *= i 8 return s 9 print(f(n)) 递归 1 def factorial_new(n): 2 3 if n==1: 4 return 1 5 return n*factorial_new(

Python递归函数的运用

什么是递归函数?在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.意义:通过一定的“基”,并按照某种规则达到重复的效果 递归函数实现斐波那契数列斐波那契数列的定义:斐波那契数列指的是这样一个数列 :1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368…这个数列从第3项开始,每一项都等于前两项之和. 关键点在于每一