数据结构—递归小结

来源:互联网 发布:淘宝店铺保证金多少钱 编辑:程序博客网 时间:2024/05/22 12:00
为什么数学归纳法能构成一个证明。
对于N=1,改定理成立,这称为基本情况。
使用归纳假设,假设对于任意K,定理成立,如果k成立,那么k+1也会成立。
这里针对一个例子来说一下数学归纳法的使用
 
 
对于求前N项的和,S(N)=S(N-1)+N的递归形式:
public static long s(int n){
    if(n==1)return 1;//基本情况
    else return s(n-1)+n;//推进
}
任何递归必须有1基本情况(递归出口)和2向基本情况的推进两种条件
 
问题一:
不能处理N>=8882 (从书上看的,不知道为什么),这里思考一个问题,栈溢出的时候N是多少,怎么分析,网上很多地方说道栈的大小其实不固定。如果针对一个32位的系统来说,栈溢出的条件就是最大的栈深*占用的字节数小于等于理论的最大内存数吗,32位内存最大是4G。不知道这么理解对不对。这个地方不太明白,有理解的比较深求指教。

 
分析递归调用的栈空间消耗
32位系统中
4字节返回地址;
4*n字节参数,n位参数个数
12字节寄存器保护器EBP ESI EDI
4*m字节局部变量,m是内部变量个数
一次调用内存大小是1+4*n+12+4*m=4+4+12=20B (针对求N项和的递归函数)


fibonacci数列问题。

三种算法1非递归算法2递归算法3矩阵算法

递归算法的时间复杂度是O(2^N)

递归算法计算有很多的重复项目,F(n)=F(N-1)+F(N-2),F(N-1)=F(N-2)+F(N-3) 其中F(N-2)被计算了两次,随着N的增大,重复的数量会越来越多。时间复杂度也会越来越大。

时间复杂度考虑的是最坏的情况,因此这里将F(N)写成树的形式,可以看的比较明显,是一颗二叉树,虽然不是满的二叉树,考虑最坏的情况下,利用满二叉树计算时间复杂度,时间复杂度就是计算的次数,计算的次数就是数的节点的个数,2^n-1,n指的是树的深度,也是要求的fib的n的值。可见,时间复杂度是值数级别的o(2^n)

空间复杂度是O(N)

递归最深的那一次所耗费的空间足以容纳它所有递归过程。递归产生的栈侦是要销毁的,所以空间也就释放了,要返回上一层栈侦继续计算+号后面的数,所以它所需要的空间不是一直累加起来的,之后产生的栈侦空间都小于递归最深的那一次所耗费的空间。

递归的深度*每次递归所需的辅助空间的个数 ,所以空间复杂度是:O(N)

fibonacci数列的通项公式


计算a与b的最大公约数 ,这里也是用的第归去求解(求最大公约数在加密解密中有广泛的应用)
辗转相除法,欧几里得算法
public static long gcd(long a,long b){
    if(b==0)return a;
    else
    a-b>b?return gcd(a-b,b):return gcd(b,a-b);
}
执行的流程为 : gcd(70,25)->gcd(45,25)->(25,20)->(20,5)->(15,5)->(10,5)->(5,5)->(5,0)=5  结果为5


优化:相减与求模在本质上是相等的。求模是一种优化,求模后的值一定小于b

public static long gcd(long a,long b){
    if(b==0)return a;
    else
        return gcd(b,a%b);
}

执行流程:gcd(70,25)->gcd(25,20)->(20,5)->(5,0)  结果为5(确实少了一些计算量)


原创粉丝点击