022 Python初学笔记--递归的概念和使用:阶乘、斐波那契数列、汉诺塔、十进制转二进制

一、递归算法的常识:


  • 递归需要满足的两个基本条件:

①函数调用自身

②函数设置了正确的返回值


  • 按照递归的特性,在编程中不得不使用递归的情况:

例如汉诺塔,目录索引(检查目录里面是否还有目录),快速排序,树结构的定义等如果使用递归,会是算法的效率事半功倍,否则将会导致程序无法实现或难以理解


  • 用递归去计算阶乘问题或斐波那契数列是很糟糕的算法,为什么?

①递归的实现是函数对自身的调用,每次函数的调用都需要进栈、出栈、保存和恢复寄存器的栈操作,在这上面是非常消耗时间和空间的。

②另外,如果递归一旦忘记了返回,或者错误设置了返回条件,那么执行这样的递归代码就会变成一个无底洞,只进不出。在使用递归时一定要十分的注意。


二、递归的使用:

  • 阶乘:

>>> #递归法求阶乘
>>> def factorial(x):
	if x==1:
		return 1
	else:
		return x*factorial(x-1)

	
>>> factorial(5)
120

>>> #迭代法求阶乘	
>>> def fac(y):
	sum=y
	for i in range(1,y):
		sum*=i
	return sum

>>> fac(5)
120
  • 斐波那契数列:

①n=1或n=2时,f(n)=1

②n>2时,f(n)=f(n-1)+f(n-2)

>>> #递归求斐波那契数列
>>> def fibo(n):
	if n==1 or n==2:
		return 1
	else:
		return fibo(n-1)+fibo(n-2)

	
>>> fibo(20)
6765

>>> #迭代求斐波那契数列
>>> def fab(m):
	list1=[]
	list1.append(m)     
	for i in range(1,m+1):
		if i==1 or i==2:
			list1.append(1)
		else:
			list1.append(list1[i-1]+list1[i-2])
	return list1[m]

>>> fab(20)
6765
  • 汉诺塔问题:

有X,Y,Z三根柱子。X柱子由上到下放置着n个由小到大的盘子,需要将这n个盘子借助柱子Y全部移动到柱子Z上。在移动的过程中,每根柱子的下方的盘子的不能比上方的盘子小。

>>> #递归求汉诺塔问题
>>> def hanof(n,x,y,z):   #n:盘子个数;x:盘子的初始位置;z:盘子的最终位置;y:盘子借助y从x移动到z
	if n==1:
		print(x,'-->',z)
		return
	else:
		hanof(n-1,x,z,y)   #将x上的n-1个盘子借助z移动到y上
		print(x,'-->',z)   #将x上的盘子移动到z
		hanof(n-1,y,x,z)   #将y上的n-1个盘子借助x移动到z
#结果
>>> hanof(1,'X','Y','Z')
X --> Z
>>> hanof(3,'X','Y','Z')
X --> Z
X --> Y
Z --> Y
X --> Z
Y --> X
Y --> Z
X --> Z

注:

  1. 若x上只有一个盘子,直接将x上的盘子移动到z上。
  2. 若x上有多个盘子,将x上的前n-1个盘子借助z移动到y上,再将x上剩下的一个盘子移动到z上。
  3. 最后将y上的盘子移动到z上。在此移动过程中,y柱子为初始柱子,z柱子还是最终的柱子,x柱子相当于中间的柱子,然后再进行上述步骤的移动,直到所有的盘子都移动完为止。
  • 十进制转二进制(要求以字符串的形式返回)

    >>> #递归求进制转换
    >>> def Dec2Bin(dec):
    	result=''
    	if dec:
    		result+=Dec2Bin(dec//2)
    		return result+str(dec%2)
    	else:
    		return result
    
    	
    >>> Dec2Bin(10)
    '1010'
    
    >>> #利用python内置函数求进制转换
    >>> bin(10)    
    '0b1010'

     

你可能感兴趣的:(python)