四、递归(一)

1. 用递归要明确两大条件

(1)base情况:找出最重要的Base条件,即递归结束的条件  

(2)数学归纳法:找出f(n)与f(n-1)或者f(n-2)等的关系。

2. 例子

(1) 累加  从1+2+3+……+n 

def mysum_recursive(n):
    if n == 0: # base情况 
        return 0
    return n + mysum_recursive(n-1)    # f(n) 与 f(n-1)的关系,f(n) = n + f(n-1)

(2)累乘

def factorial_recursive(n):
    if n == 1: # base 情况
        return 1
    return n * factorial_recursive(n - 1)  # 找出f(n) 与 f(n-1)的关系 f(n) = n*f(n-1)

(3)斐波那契数列:0,1,1,2,3,5,8,11,......

def fibonacci1(n):  # 时间复杂度为O(2^n)   # 像二叉树一样不断扩展 
    assert(n>=0)
    if (n <= 2): # base情况 
        return 1
    return fibonacci2(n-1) + fibonacci2(n-2) # 找出f(n) 与 f(n-1)的关系
def fibonacci2(n):
    assert(n>=0)
    a, b = 0, 1 # base  
    for i in range(1, n+1): # 时间复杂度为O(n)
        a, b = b, a + b   
    return a 

(4)打印尺子

1

1 2 1

1 2 1 3 1 2 1

1 2 1 3 1 2 1 4 1 2 1 3 1 2 1

def ruler_bad(n): 
    assert(n>=0)
    if (n==1): # base 情况
        return "1"
    return ruler_bad(n-1) + " " + str(n) + " " + ruler_bad(n-1)  # f(n) 与f(n-1)的关系为f(n) = f(n-1) + n + f(n-1) 时间复杂度为O(2^n)

def ruler(n):
    assert(n>=0)
    if (n==1): 
        return "1"
    t = ruler(n-1) # 只算一遍f(n-1) 时间复杂度为O(n)
    return t + " " + str(n) + " " + t

def ruler2(n):
    result = ""
    for i in range(1, n+1):
        result = result + str(i) + " " + result
    return result

(5)数学表达式

Given two integers a ≤ b, write a program  that transforms a into b by a minimum sequence of increment (add 1) and unfolding (multiply by 2) operations. For example:

23 = ((5 * 2 + 1) * 2 + 1) 

113 = ((((11 + 1) + 1) + 1) * 2 * 2 * 2 + 1)

分析:  

A: b>2a: 如果b为奇数,则先用b减去1,再一直除以2, 否则一直除以2,知道b<2a为止。  

B: b<2a: a一直加1一直加到和b相等为止  

C: b=a:返回a 

def intSeq(a, b):
    if (a == b): # base 情况
        return str(a)
    
    if (b % 2 == 1):  # b为奇数的情况下,让其变为偶数再计算。变为偶数了就不断的乘2就可以了。
        return "(" + intSeq(a, b-1) + " + 1)"
    
    if (b < a * 2): # b < 2a的情况,是f(a, b) = f(a, b-1) + 1,例如a = 5, 2a = 10 , 6,7,8,9是小于2a的,需要不断地加1而又不能乘2 
        return "(" + intSeq(a, b-1) + " + 1)"
        
    return intSeq(a, b/2) + " * 2";   # 一直除以2 

(6)汉诺塔

# 先把f(n-1)从最左面(start)移到中间(by),再把f(1)从最左面(start)移到最右边(end),最后把f(n-1)从中间(by)移动到最右面(end)。
def hanoi(n, start, end, by):
    if (n==1): # base   f(1) 是只有一个的时候,此时只需要把它从最左面移动到最右面即可。
        print("Move from " + start + " to " + end)
    else:
        hanoi(n-1, start, by, end)
        hanoi(1, start, end, by) 
        hanoi(n-1, by, end, start)

  

  1. 找出最重要的Base条件,即递归结束的条件
posted @ 2020-12-23 21:19  RamboBai  阅读(138)  评论(0编辑  收藏  举报