zoukankan      html  css  js  c++  java
  • python递归

    Python递归函数

     

      本篇主要介绍Python中函数的递归,还是从三个方面了解:什么是递归;递归有什么好处;递归的具体用法是什么样的;

    一、什么是递归?

      在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。记住哦->在函数内部调用其他函数不是函数的嵌套,而在函数内部定义子函数才是函数的嵌套。

    递归的特性:

      1、递归函数必须有一个明确的结束条件。

      2、每进入更深一层的递归时,问题规模相对于上一次递归都应减少

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

      4、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

      先看一个例子,一个关于实现叠加的两种方法的例子:

    复制代码
    import sys
    #通过循环来实现叠加
    def sum1(n):
        '''
        1 to n,The sum function
        '''
        sum = 0
        for i in range(1,n + 1):
            sum += i
        return sum
    
    #通过函数的递归来实现叠加
    def sum2(n):
        '''
        1 to n,The sum function
        '''
        if n > 0:
            return n + sum_recu(n - 1)    #调用函数自身
        else:
            return 0
    
    print("循环叠加-->",sum1(100))
    print("递归叠加-->",sum2(100))
    
    #两者实现的效果均是:5050
    复制代码

       从上述例子中可以看出,两者都可以实现叠加的效果。那么后者相对前者有什么优缺点呢?

    二、递归函数有啥优缺点?

      递归函数的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

      递归函数的缺点:使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

      把上面的递归求和函数的参数改成10000就导致栈溢出!

      当然也可以通过尾递归来对递归的栈溢出进行优化。这里就不详细介绍了。请参考:http://www.open-open.com/lib/view/open1480494663229.html

    三、通过实例来介绍函数递归:

      下面我们通过一个问路的例子,更好的理解递归:

    复制代码
    #假如街上有这么一群人,我想问知道长沙的小吃街在哪。其中只有狗菲(大吃货)知道在哪。
    names=["我","刘二","张三","李四","狗菲","王五"]
    #问路
    def ask_way(lis):
        #街上就我一个人的情况下
        if len(lis)==1:
            return "没有人知道这个地方在哪。"
        #街上不只我一个人的情况下,先问第一个人
        name=lis.pop(0)
        #如果这个人是狗菲,那么问到路,递归结束
        if name=="狗菲":
            return "狗菲说:长沙的小吃街在天心区南门口!!"
        #如果这个人不知道路,就去问下一个人,下一个人就好把结果告诉这个人。
        print("<%s>问:你[%s]好,请问你知道长沙的小吃街在哪吗?" % (name, lis[0]))
        print("不好意思,我帮您问一下%s,他可能会知道!!
    "%lis[0])
        res=ask_way(lis)
        if name != "我":
            print("<%s>说:%s" % (name, res))
        return res
    
    #输出结果为:
    """
    <我>问:你[刘二]好,请问你知道长沙的小吃街在哪吗?
    不好意思,我帮您问一下刘二,他可能会知道!!
    
    <刘二>问:你[张三]好,请问你知道长沙的小吃街在哪吗?
    不好意思,我帮您问一下张三,他可能会知道!!
    
    <张三>问:你[李四]好,请问你知道长沙的小吃街在哪吗?
    不好意思,我帮您问一下李四,他可能会知道!!
    
    <李四>问:你[狗菲]好,请问你知道长沙的小吃街在哪吗?
    不好意思,我帮您问一下狗菲,他可能会知道!!
    
    <李四>说:狗菲说:长沙的小吃街在天心区南门口!!
    <张三>说:狗菲说:长沙的小吃街在天心区南门口!!
    <刘二>说:狗菲说:长沙的小吃街在天心区南门口!!
    
    狗菲说:长沙的小吃街在天心区南门口!!
    """
    复制代码

      其实用图来表示就是:

      

      从上面的图示我们也可以知道:递归值的返回时返回到上一层,而其他的层在执行的过程中,均处于等待答案的过程中。

  • 相关阅读:
    HDU 5744
    HDU 5815
    POJ 1269
    HDU 5742
    HDU 4609
    fzu 1150 Farmer Bill's Problem
    fzu 1002 HangOver
    fzu 1001 Duplicate Pair
    fzu 1150 Farmer Bill's Problem
    fzu 1182 Argus 优先队列
  • 原文地址:https://www.cnblogs.com/zxy6/p/11637552.html
Copyright © 2011-2022 走看看