时间/空间复杂度浅析
2015-09-11 17:34
169 查看
渐进分析
可以通过精确的计算其执行的语句或者引用的对象的数量来估计数据结构的性能或者复杂度。但是现代计算机体系结构的执行速度会相差10倍甚至更多,因此详细的计算不能为我们提供更多关于一个特定实现的实际运行时间的信息,因此对于行为进行如此详细的分析一般是没有必要的。数据结构和算法之间的区别,往往可以通过观察在解决许多问题是所表现出来的性能模式来确定。时间和空间复杂度
设计数据结构和算法时,关心的是当问题的规模增大时,各种性能参数所表现出来的趋势。一般使用渐近线或者大O分析。定义
一个函数f(n)是O(g(n)),当且仅当存在两个正的常量,c和n0,对于所有的n>=n0,有|f(n)|<=c*g(n)。或者说是当且仅当存在一个常数c使得c*g(n)的增长见尽快与f(n)。其中f是问题规模的一个函数,描述了一些资源(时间、空间等)的使用情况,c为一个正数。
1. 可以将g(n)看成是与f(n)的上线成比例的,在经过了某点后,f(n)不会超过”适当规模“的g(n),即在g(n)扩大到一个必要的范围时(乘以c),成为f(n)的上限。如果f(n)是O(g(n)),那么它也是O(10*g(n))和O(5+g(n))。
2. 关注的是长期行为,即直到某个点,可以忽略“小问题”和一些规则的行为,这个点即为n0。
推到时间复杂度的大O阶
1. 用常数1取代运行时间中的所有加法常数 2. 在修改后的运行时间中,只保留最高阶项 3. 如果最高阶不是1,去除其系数(系数变为1)
常见情况
如果一个函数的上限由一个常数决定,该函数是O(1)的;
如果一个函数的增长与问题的规模成比例时,或者是线性时,称其为O(n)的;
如果一个函数以多项式的速度增长,是O(n^c)的;
示例
乘法表(时间复杂度)
for(int i=0;i<n;i++){ //1 for(int j=0;j<=i;j++){ //2 System.out.print(i*j + " "); //3 } System.out.println(); //4 }
假设第3行使用的时间为常数c1,第4行使用的时间为c2,那么总体需要的时间为:
(c1+c2)+(2c1+c2)+……+(nc1+c2)=(c1/2) * (n^2)+(c2+c1/2)*n 即为O(n^2)
因数表(空间复杂度)
1到10的因数表如下:1
1 2
1 3
1 2 4
1 5
1 2 3 6
1 8
1 2 4 8
1 3 9
1 2 5 10
代码如下:
{ Vector table =new Vector(); for(int i=1;i<=n;i++){ Vector factors =new Vector(); for(int f=1;f<=i;f++){ if(i%f ==0)factors.add(new Integer(f)); } table.add(factors); } return tables; }
生成表的时间复杂度为O(n^2);
空间复杂度:可以看到每个因子f出现在行数为f的整数倍的行中,即在n行中,不会有超过n/f行还有f。因此一个表的大小为:
n+n/2+n/3+n/4+……+1=n(1+1/2+1/3+……1/n)
(1+1/2+1/3+……1/n)为1/x在[1,n]上的积分,即为ln(n),故表的大小为nln(n),即空间复杂度为nln(n)
相关文章推荐
- Android Canvas drawText实现中文垂直居中
- Calendar用法随笔
- memcached 基于libevent的事件处理
- this关键字和索引器
- c++中输入与输出流
- python install 2.7.10
- docker 创建容器 时的 注意事项
- AutoCompleteTextView与MultiAutoCompleteTextView
- PAT 1046-1057
- ios 中使用SBJson拼接和解析json
- lintcode-排颜色II-143
- 又绕了一个弯
- 多线程之NSOperation(下)
- C# Socket的安全关闭
- C语言中函数参数入栈的顺序
- UE4使用第三方库
- 小菜的前端编程散谈(2)
- 他,如此与众不同 ——法国《世界报》专版聚焦DJ
- DIV层居中
- struct stat结构体的详解和用法