递归
递归
什么是递归?
答:通俗来讲递归就是自己调用自己
递归函数包含以下两条:
1.当函数直接返回值时有基本实例
2.递归实例,包括一个或多个问题较小部分的递归调用
综上所述递归函数的关键就是将问题分解为小部分,递归不能永远继续下去,因为它总是以最小的可能性问题结束,而这些问题又储存在基本的实例中的。
两个经典的:阶乘和幂
- 阶乘
我们知道n的阶乘定义为:n x (n-1) x (n-2) x...x 1.
在很多数学应用中都会用到它。那么怎么计算呢?可以使用循环:
def factorial(n):
result = n
for i in range(1,n):
result *= i
return result
print(factorial(5))
"D:\Program Files\python.exe" "E:/py_code/day 3.py"
120
这个方法可行而且很容易实现。它的过程主要:首先,将result依次与1~n-1的数相乘,最后返回结果。
所以现在可以看下数学上对阶乘定义:
1.1的阶乘是1;
2.大于1的数n的阶乘是n乘以(n-1)的阶乘
现在考虑如何将定义实现为函数。
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
print(factorial(5))
"D:\Program Files\python.exe" "E:/py_code/day 3.py"
120
这就是定义的直接实现。函数调用factorial(n)是和调用factorial不同的实体。
- 幂
考虑到另外一个例子。假设需要计算幂,就像内建的pow函数或者**运算符一样。可以用很多种方法定义一个数幂。如:power(x,n)(x为n的幂次)是x自乘n-1次的结果(所以x用做乘数n次)。
def power(x,n):
result = 1
for i in range(n):
result *=x
return result
print(power(2,3))
"D:\Program Files\python.exe" "E:/py_code/day 3.py"
8
Process finished with exit code 0
程序很小巧,接下来把它改编成为递归版本:
def power(x,n):
if n == 0:
return 1
else:
return x * power(x,n-1)
print(power(3,2))
"D:\Program Files\python.exe" "E:/py_code/day 3.py"
9
Process finished with exit code 0
通过上面的例子,那么递归有什么用?就不能用循环代替吗?答案是肯定的,在大多数情况下,递归更加易读,有时会大大提高可读性,尤其当读程序的人懂得递归函数的定义的时候。尽管可以避免编写使用递归的程序,但作为程序员来说还是要理解递归算法以及其他人写的递归程序,这也是最基本的。
另外一个经典:二分查找
什么是二分查找?
简单的一个例子假如有一个文件中按小到大存储
着100000个数值。现在要你需要知道7000在不在这个
文件的数列中。对与这个问题可能有很多人会想
到用for循环遍历整个数值列表,但是是否有相过
假如7000在列表的最后那就意味着你的遍历整个列表
才能得到结果,很显然这个方法很浪费时间。所以就有
了二分算法就可以在几步就可以判断:
第一步:取数值列表的中间值a,然后将它与7000进行对比
第二步:如果a>7000,则就可以将列表中一半的数值排除
第三步:现在再从小于a的一半的数值中再取中间值b,与7000
进行对比,依次进行类推。就可以很快求出结果
下面就来实现一个二分查找:
def search(sequence,number,lower,upper):
if lower == upper:
assert number == sequence[upper]
return upper
else:
middle = (lower + upper) // 2
if number > sequence[middle]:
return search(sequence,number,middle+1,upper)
else:
return search(sequence,number,lower,middle)