目录
一、什么是递归
计算机程序中,迭代通常使用循环描述,耳熟能详的莫过于for和while循环。另一种完全不同的迭代实现方式就是递归。
递归是一种技术,通过一个函数在执行过程中一次或多次调用其本身,直至调用执行完成。下边将从两个例子说明递归:1、利用递归使用阶乘函数;2、使用递归实现二分查找算法。
二、阶乘函数
1、阶乘函数
阶乘函数数学定义:
一个正整数n的阶乘表示为n!,它被定义为从1到n的整数的乘积,如果n=0,则规定n!=1。更为正式的定义为:对于任何整数,
通常,对于一个正整数n,可定义。上述递归定义可以形式化为:
2、递归实现
代码段:
def factorial(n):
if n==0:
return 1
else:
return n*factorial(n-1)
if __name__ == "__main__":
n = 4
c = factorial(n)
print(c)
如上函数没有任何显式的循环。迭代通过函数的重复递归调用实现。当函数每被调用一次,其参数n就变小一次,当n==0时,返回1,递归调用也就停止。
如下图,n=4时候的阶乘计算过程:
3、算法分析
为计算factorial(n) 共执行了n+1次函数调用,参数从第一次调用时的n下降到第二次调用的n-1,直至调用到n=0时,操作的总次数为O(n),每次调用占的操作次数为O(1)。
三、二分查找
1、二分查找
该算法用于在一个含有n个元素的有序序列中快速定位目标值。这是最重要的计算机算法之一,也是我们经常顺序存储数据的原因。
当序列无序时,寻找一个目标值的标准方式是使用循环来检查每一个元素,直至找到目标值或检查完数据集中的每个元素。这就是所谓的顺序查找算法。因为最坏的情况下每个元素都需要检查,这个算法的时间复杂度是O(n)(即线性的时间)。
当序列有序并且可以通过索引访问时,有一个更有效的算法,即二分查找。对于任意的索引j,在索引0,……,j-1上存储的所有值都小于索引j的值,并且在索引j+1,……,n-1上存储的所有值大于或等于索引j上的值。在搜索目标值时,这种观察能使我们迅速找到目标值,该算法维持 两个参数low和high,这样可使所有的候选条目的索引位于low和high之间,首先,low=0和high=n-1。然后 比较目标值和中间值,即索引mid的数据。
- 如果目标值等于mid索引的数据,查找成功并且终止
- 如果目标值小于mid索引的数据,则high=mid-1,查找的数据为索引为low到high之间的数据
- 如果目标值大于mid索引的数据,则low=mid+1,查找的数据范围为low到high之间的数据
- 如果low>high 索引范围[low,high]为空,查找不成功。
2、递归实现二分查找算法
代码段(python3)
def binary_search(data,target,low,high):
if low>high:
return False
else:
mid = (low+high)//2
if target == data[mid]:
return True
elif target < data[mid]:
high = mid-1
return binary_search(data,target,low,high)
else:
low = mid+1
return binary_search(data,target,low,high)
查找过程图解:
3、算法分析
一次二分查找中,数据条目为n,进行第一次二分查找调用后,数据条目至多为n/2,进行第二次调用后,至多为n/4,以此类推。一般情况下,对于n个数据,进行j次二分查找调用后,剩余的数据 数量至多为。最坏的情况下,没有更多的数据时递归调用停止(不成功的查找)。进行递归调用的最大次数,有最小的整数r,使得,即 = 。意味着二分查找的时间复杂度为。