Python学习笔记(22-23)递归

学习主题:递归
学习日期:2020-02-06
Python 版本:3.7.4

第22讲

一个问题:求阶乘

1.使用普通循环迭代做

#使用普通循环迭代做
def  factorial_fun(n):#阶乘的英文为factorial
    result=n
    for ii  in range(1,n):
         result=result *ii
         
    return result

number=int(input('请输入一个数字'))
print(number)
result1=factorial_fun(number)
print(result1)

#运行结果如下
>>> 
 RESTART: C:/Users/SNIPER/AppData/Local/Programs/Python/Python37/SniperPyWorks/exam3.py 
请输入一个数字5
5
120
>>> 

2.使用递归做

首先说下,递归的两个要素:
(1)确定自身的最初返回值
(2)调用函数自身

#使用递归做
def  factorial_fun(n):
    if n==1:
        return 1
    else:   
         return  factorial_fun(n-1)*n

number=int(input('请输入一个数字'))
print(number)
result1=factorial_fun(number)
print(result1)


#运行结果
>>> 
 RESTART: C:/Users/SNIPER/AppData/Local/Programs/Python/Python37/SniperPyWorks/exam4.py 
请输入一个数字5
5
120

递归递归,有传递,也得有回归。传递体现在用上一步的结果,回归体现在最终由返回值而不是死循环。

递归会占用内存很大,Python中将递归限制在100层,比如上面的阶乘这个例子,就没有必要用递归。递归有递归的好处,后边有举例。

经典问题:斐波那契数列
斐波那契数列又因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。
如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?

我们不妨拿新出生的一对小兔子分析一下:
第1月小兔子没有繁殖能力,所以还是1对
2个月后,生下一对小兔对数共有2对
3个月以后,老兔子又生下1对,因为小兔子还没有繁殖能力,所以一共是3对
------
依次类推可以列出下表:
在这里插入图片描述
成兔对数=前月成兔对数+前月幼仔对数
总体对数=本月成兔对数+本月幼仔对数

可以看出幼仔对数、成兔对数、总体对数都构成了一个数列。这个数列有关十分明显的特点,那是:前面相邻两项之和,构成了后一项。

在这里插入图片描述
其实,幼崽对数,成兔对数,总体对数 都是斐波那契数列啦

可以观察到,斐波那契数列的特点是:当前值=之前两个值的和。

在中学我们就学过,这个数列是 找不到通式的。这种数列,一般就是给出初始值,以及递推关系式。根据这两个条件,我们就可以推出第N项的数值。

def  FibonacciSequence(n):
    'Code for  Fibonacco  Sequence  '
    if n<=2:
        return 1
    else:
        return  FibonacciSequence(n-1)+FibonacciSequence(n-2)


n=input('the month')
n=int(n)
a=FibonacciSequence(n)
print(a)

#运行结果
>>> 
 RESTART: C:/Users/SNIPER/AppData/Local/Programs/Python/Python37/SniperPyWorks/exam5.py 
the month10
55
>>> 

在这里插入图片描述

第23讲

汉诺塔游戏
这个游戏大家都知道,大概说下要点:每次只能挪动一个盘子,把A柱上的搬到C柱上,要求小盘子必须在大盘子上面。
在这里插入图片描述
使用递归求解汉诺塔

解决一个问题最重要就是:思路与方法。不考虑方法就是蛮干,看起来很努力实则是假努力。

思路是什么?
了解过这个游戏代码实现的人,肯定会说,这个游戏用递归实现。但是你要是再深入问一句,为什么这个游戏可以采用递归,或者是为什么递归可以实现这个游戏。
能够回答上来的人,就很少了。

那么,我们先分析下这个游戏:
(1)如果只有一个盘子
step1:我们就把它从A柱上直接搬到C柱上。
(2)如果只有两个盘子,
step1:我们得先把第1个放在B上,把B作为暂放柱子。
step2:然后又是把第2个那个盘子放在C上:
step3:再把第1个盘子从B放到C上。
(3)如果是三个盘子呢。我们先跳到最后几步想想。
肯定是先把B作为作为暂放柱,第1个和第2个盘子放到B柱上;
然后再把第3个盘子从A放在C上。
然后,再借助A柱作为暂放柱,把1,2盘子放在C上。
(4)如果是N个盘子呢,,,,,
肯定是先把B作为作为暂放柱,把前N-1个盘子放到B柱上;
然后再把第N个盘子从A放在C上。
然后,再借助A柱作为暂放柱,把前N-1盘子放在C上。
仔细想想:
上面(3)中的步骤1类似整个的步骤(2);
上面(3)中的步骤2类似(1)中的step1;
上面(3)中的步骤3就类似整个的步骤(2);
同理类推到N个盘子的操作步骤。

这时候,就可以回答我提出的那个问题了,为什么可以采用 递归 来实现。
递归的最重要特点就是:在本情况中能够利用上一情况的结果或者方法。
显然上面是用到了。
还要注意我上面说的是‘’类似’二字。

代码如下:

#输出汉诺塔的操作攻略

def hanoi(n,x,y,z):
    if n==1:
        print(x,'--->',z)
    else:
        hanoi(n-1,x,z,y)
        print(x,'--->',z)
        hanoi(n-1,y,x,z)


n=input('the  number of plane: ')
n=int(n)
hanoi(n,'A','B','C')

运行结果:
在这里插入图片描述
汉若塔的这个游戏,不使用 递归 ,是真的很难很难写出来的。

发布了75 篇原创文章 · 获赞 45 · 访问量 7313

猜你喜欢

转载自blog.csdn.net/hahahahhahha/article/details/104190485