int*a和int n是算法本身需要的,数组的变量大小,算的是额外需要的空间大小,就是计算这个算法时候定义的变量。这个变量不会定义n个i
在冒泡排序的栈帧里面,编译器先定义一个end,进行迭代,再定义一个i,然后循环结束i销毁,再循环上来的时候,再定义一个i,这个i和之前的i共用的是同一块空间。额外最多使用了两个空间,再加上exchange就是三个,常数个是o(1),所以空间复杂度是o(1)
开了n+1个的数组,先给第零个和第一个,第零个和第一个可以算出第二个...用了n+1个开辟空间,额外空间用了n+多个,i啊什么的额外空间,但是是o(N)这个量级
之前递归算法的时间复杂度是o(2^N),优化成循环以后,就到o(N)了,跑了n-2次,比递归效率提高了很多
现在是求这个数组,如果只想求第N个数,三个变量迭代走就可以,一个变量记录第零个和第一个,先算第二个,第一个和第二个倒一下就可以算第三个,依次往后算就算第n个的话,空间复杂度还可以优化到o(1)
阶乘递归就是不断在建立栈帧,每次调用建立一个栈帧,每个栈帧里面额外定义的变量是0,没有定义,栈帧里面还有保存一些寄存器什么的,栈帧里面还要有一些空间,但都可以认为是常数个,每个栈帧都认为是常数个,递归n次建立n个栈帧,所以空间复杂度是o(N).递归算法其实要去看栈帧的消耗,看递归的深度
如果是O(2^N)栈已经溢出了,因为栈是不大的,为什么是o(N):
空间是可以重复利用,不累计的
时间是一路不复返,累积的
Fib(N)要算Fib(N-1)和Fib(N-2),但是会先算Fib(N-1),因为( Fib(N)=Fib(N-1)+Fib(N-2) )Fib(N-1)要算Fib(N-2)和Fib(N-3),但它会先算Fib(N-2)。调用完到最低就回去了,回去的时候再继续调用的时候,也就是先算N-1,N-1递归回来以后再算这个N-2的时候再继续递归,就是右边这些递归跟左边重复利用的同样的空间,所以最多用了N层空间。
空间不累计,可以重复利用,时间左边用了,到右边用的不是同一个时间
回到Fib(N-1)向右边那边继续算,左边的调用完销毁了,右边算的是左边用的同一块空间
总结:一条路递归完回来再递归另外一条路,另外一条路和先前用的同一块空间