2012年5月7日---基于斐波那契数列的时间复杂度分析
2014-03-15 10:49
309 查看
在算法中,时间复杂度是衡量一个算法好坏的重要标准。
递归调用在算法中可以非常直观有效的解决我们的问题,但是由于其调用的时候需要花大量的时间,所以我们一般都会刻意的避免使用递归去完成我们的算法。
在这里,我就用斐波那契数列的递归构造和非递归构造来分析递归和非递归的时间复杂度。
先看具体的代码极其运行的时间:
Java代码
/*
* 比较递归和非递归求斐波那契数的时间效率
* @version 2012/5/7
* @author akon
*/
package com.akon405.www;
public class Fibonacci {
//递归求斐波那契数列
public int rFibonacci(int n){
int x=n;
if(x<=1){
return x;
}
x=rFibonacci(x-1)+rFibonacci(x-2);
return x;
}
//非递归求斐波那契数列
public int uRFibonacci(int n){
int x=1;
int y=1;
int tmp;
for(int i=2;i<n;i++){
tmp=x;
x=y;
y=y+tmp;
}
return y;
}
public static void main(String[] args) {
double d1,d2,d3;
Fibonacci f=new Fibonacci();
System.out.println("递归求斐波那契数列:");
d1=System.currentTimeMillis();
for(int i=1;i<=40;i++){
System.out.println(f.rFibonacci(i));
}
d2=System.currentTimeMillis();
d3=d2-d1;
System.out.println("递归求斐波那契数列的时间:"+d3);
System.out.println("非递归求斐波那契数列:");
d1=System.currentTimeMillis();
for(int i=1;i<=40;i++){
System.out.println(f.uRFibonacci(i));
}
d2=System.currentTimeMillis();
d3=d2-d1;
System.out.println("非递归求斐波那契数列的时间:"+d3);
}
}
Java代码
运算结果:(只保留部分结果)
Java代码
<pre name="code" class="java">递归求斐波那契数列:
1
1
2
3
5
.
.
102334155
递归求斐波那契数列的时间:4322.0
非递归求斐波那契数列:
1
1
2
3
5
.
.
102334155
非递归求斐波那契数列的时间:3.0
</pre>
通过结果就可以大致看出,递归调用的时间是非递归调用的很多倍。并且这种情况在n越大的时候越明显。
在分析算法的时间复杂度的时候,我们也可以得到相同的结果,非递归使用的是for循环,其时间复杂度为O(n)。而递归的时间复杂度则比较复杂,其分析出来为O(2^n)。
这里需要说明的就是,非递归的for循环其时间复杂度O(n)虽然很小,但是其空间复杂度缺比递归调用差得多。因为,for循环在每次循环的时候,都把相应的数值保存下来了,而递归调用却不会保存相应的数值。
递归调用在算法中可以非常直观有效的解决我们的问题,但是由于其调用的时候需要花大量的时间,所以我们一般都会刻意的避免使用递归去完成我们的算法。
在这里,我就用斐波那契数列的递归构造和非递归构造来分析递归和非递归的时间复杂度。
先看具体的代码极其运行的时间:
Java代码
/*
* 比较递归和非递归求斐波那契数的时间效率
* @version 2012/5/7
* @author akon
*/
package com.akon405.www;
public class Fibonacci {
//递归求斐波那契数列
public int rFibonacci(int n){
int x=n;
if(x<=1){
return x;
}
x=rFibonacci(x-1)+rFibonacci(x-2);
return x;
}
//非递归求斐波那契数列
public int uRFibonacci(int n){
int x=1;
int y=1;
int tmp;
for(int i=2;i<n;i++){
tmp=x;
x=y;
y=y+tmp;
}
return y;
}
public static void main(String[] args) {
double d1,d2,d3;
Fibonacci f=new Fibonacci();
System.out.println("递归求斐波那契数列:");
d1=System.currentTimeMillis();
for(int i=1;i<=40;i++){
System.out.println(f.rFibonacci(i));
}
d2=System.currentTimeMillis();
d3=d2-d1;
System.out.println("递归求斐波那契数列的时间:"+d3);
System.out.println("非递归求斐波那契数列:");
d1=System.currentTimeMillis();
for(int i=1;i<=40;i++){
System.out.println(f.uRFibonacci(i));
}
d2=System.currentTimeMillis();
d3=d2-d1;
System.out.println("非递归求斐波那契数列的时间:"+d3);
}
}
Java代码
运算结果:(只保留部分结果)
Java代码
<pre name="code" class="java">递归求斐波那契数列:
1
1
2
3
5
.
.
102334155
递归求斐波那契数列的时间:4322.0
非递归求斐波那契数列:
1
1
2
3
5
.
.
102334155
非递归求斐波那契数列的时间:3.0
</pre>
通过结果就可以大致看出,递归调用的时间是非递归调用的很多倍。并且这种情况在n越大的时候越明显。
在分析算法的时间复杂度的时候,我们也可以得到相同的结果,非递归使用的是for循环,其时间复杂度为O(n)。而递归的时间复杂度则比较复杂,其分析出来为O(2^n)。
这里需要说明的就是,非递归的for循环其时间复杂度O(n)虽然很小,但是其空间复杂度缺比递归调用差得多。因为,for循环在每次循环的时候,都把相应的数值保存下来了,而递归调用却不会保存相应的数值。
相关文章推荐
- 斐波那契数列递归算法和非递归算法以及其时间复杂度分析
- 斐波那契数列时间复杂度分析
- 以斐波那契数列为例分析递归算法的时间复杂度和空间复杂度
- 关于斐波那契数列三种解法及时间复杂度分析
- 斐波那契数列算法及时间复杂度分析
- 二分查找算法,斐波那契数列的递归及非递归。(分析时间复杂度及空间复杂度)
- 二叉堆(binary heap)的insert和build 时间复杂度分析
- 算法分析-时间复杂度分析
- 二分查找时间复杂度分析
- 快速排序算法的时间复杂度分析[详解Master method]
- 基于分析的提示应用又一例(实现复杂的TopN)
- 递归算法的时间复杂度分析
- 递归算法的时间复杂度分析
- 基于Visual C++之Windows核心编程代码分析(5)操作注册表与系统时间
- 分析Perm()函数功能、代码、时间复杂度
- 常用排序算法稳定性、时间复杂度分析(转,有改动)
- 分治法和二分法的时间复杂度简明分析
- 递归算法的时间复杂度分析[转]
- 常用排序算法稳定性、时间复杂度分析
- lisa程序的时间空间复杂度分析