python_斐波那契多种递归 尾递归,动态规划,循环,装饰器等

1、递归的特点

  • 递归算法是一种直接或间接调用自身算法的过程,在计算机编程中,递归算法对解决一大类问题是十分,它往往使算法的描述简洁而且易于理解。

    • 递归算法解决问题的特点:

      • (1)递归就是在过程或函数里调用自身

      • (2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

      • (3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低,所以一般不提倡用递归算法设计程序。

      • (4)在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储,递归次数过多容易造成栈溢出等。

2、递归的要求

  • 递归算法所体现的“重复”一般有三个要求:

    • (1)每次调用在规模上都有所缩小(通常是减半)

    • (2)是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出作为后一次的输入)

    • (3)在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模位达到直接解答的大小为条件)无条件递归调用将会成为死循环而不能正常结束。

正常版递归求斐波那契

# -*- coding: utf-8 -*-
# @Time    : 2018/12/13 18:37
# @author  : cd

from functools import wraps
import time

# 递归
def foo(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    return foo(n - 1) + foo(n - 2)


# 动态规划递归
def d_foo(n, temp={}):
    if n <= 2:
        return 1
    try:
        return temp[n]
    except KeyError:
        temp[n] = d_foo(n - 1) + d_foo(n - 2)
        return temp[n]


# 尾递归
def t_foo(num,res,temp):
    if num == 0:
        return res
    else:
        return t_foo(num - 1, temp, res + temp)


# 循环实现递归
def foo_circle(num):
    '''
    直接使用循环来求解
    '''
    a=0
    b=1
    for i in range(1,num):
        c=a+b
        a=b
        b=c
    return c


# 装饰器
def cached(func):
    cached_dict = {}

    @wraps(func)
    def new_func(*args):
        if args not in cached_dict:
            cached_dict[args] = func(*args)
        return cached_dict[args]

    return new_func


@cached
def foo_(n):
    if n <= 2:
        return 1
    return foo_(n - 1) + foo_(n - 2)


if __name__ == "__main__":
    list_num = [10, 20, 30, 40]
    for i in list_num:
        start_time = time.time()
        print(foo(i))
        end_time = time.time()
        print("正常递归  第{}个数:".format(i), end_time - start_time, "\n")

        start_time = time.time()
        print(d_foo(i))
        end_time = time.time()
        print("动态规划实现  第{}个数:".format(i), end_time - start_time, "\n")

        start_time = time.time()
        print(t_foo(i, 0, 1))
        end_time = time.time()
        print("尾递归实现  第{}个数:".format(i), end_time - start_time)

        start_time = time.time()
        print(foo_circle(i))
        end_time = time.time()
        print("循环实现  第{}个数:".format(i), end_time - start_time)

        start_time = time.time()
        print(foo_circle(i))
        end_time = time.time()
        print("装饰器实现  第{}个数:".format(i), end_time - start_time)
# output
55
正常递归  第10个数: 0.0 

55
动态规划实现  第10个数: 0.0 

55
尾递归实现  第10个数: 0.0 

55
循环实现  第10个数: 0.0 

55
装饰器实现  第10个数: 0.0 

6765
正常递归  第20个数: 0.004998445510864258 

6765
动态规划实现  第20个数: 0.0 

6765
尾递归实现  第20个数: 0.0 

6765
循环实现  第20个数: 0.0 

6765
装饰器实现  第20个数: 0.0 

832040
正常递归  第30个数: 0.5676724910736084 

832040
动态规划实现  第30个数: 0.0 

832040
尾递归实现  第30个数: 0.0 

832040
循环实现  第30个数: 0.0010018348693847656 

832040
装饰器实现  第30个数: 0.0 

102334155
正常递归  第40个数: 70.74423336982727 

102334155
动态规划实现  第40个数: 0.0 

102334155
尾递归实现  第40个数: 0.0 

102334155
循环实现  第40个数: 0.0 

102334155
装饰器实现  第40个数: 0.0 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值