算法分析
算法分析主要集中在时间复杂度和空间复杂度
这里也只是有所了解,算法中常见的就那几个级别,具体还是要看后面的算法再了解
大O表示法
T(N) = O(f(N))
表示T(N)de增长率小于等于f(N),也是在算法分析中最主要使用的表达方式。
f(N)表示的是算法T(N)增长率的一个上界,他不需要细致的描述,只需要粗糙的表示算法增长率的一个数量级即可。
1 T1(N) + T2(N) ~ O(max(f1(N) , f2(N) ))
2 T1(N) * T2(N) ~ O(f1(N) * f2(N))
3 对于任意的常数k,有 (log N)^k ~ O(N) [对数增长十分缓慢]
PS:对于计算机科学中,除非有特殊的声明,否则log都是以2为底的
时间复杂度
时间复杂度是基础语句执行次数T(n)的数量级问题。
涉及到主要问题:基础语句,执行次数
- 执行次数:
1 每一次的常规执行都是1
2 声明是不计时间的
3 if/else的判断执行次数是1,因为他只能执行if或者else
- 基础语句:就是执行次数最多的语句,例如最深层次的嵌套语句。
- 分析策略 :
- 1 从最深层次部分向外开展
- 2 如果有方法调用,首先分析调用的方法
- 3 如果有递归过程,可以采用迭代法计算
- 递归迭代法 :
- 1 首先得出迭代递推式
public int function(int n) {
if(n == 1) {
return 1;
}else{
return n*function(n-1);
}
}
/**
根据这个代码段,我们得到单次T(n)执行次数是 1 + T(n-1)的次数
有 T(N) = 1+T(N-1);
**
-
- 2 迭代递推
T(N) = T(N-1) + 1
= T(n-2) + 1 + 1
= T(n-3) + 1 + 1
=....
= T(n-k) + k
得到这个一般式,利用T(1)=1的开口,另n-k=1,有k=n-1,则T(N)=N-1 ~ O(N)
常见复杂度
- 常数级别 O(1)普通语句
- 线性级别 O(N) 循环
- 平方级别 O(N^2) 双层嵌套
- 立方级别 O(N^3) 三层嵌套
以上都比较好分析
分析算法最混乱的集中在对数方面,呈对数的都有一些特殊性,最常见的也就是二分策略、分治策略
PS:对数的底数和增长数量级并无关系,一般说明对数级别的时候就是logN
- 对数级别 O(logn) 二分策略-二分查找
- 线性对数级别 O(NlogN) 分治策略-归并排序
- 指数级别 O(a^N) 穷举查找-检查所有子集
对数~分治策略,二分策略
- 分治策略:一个问题分成两部分,先执行一部分,再执行另外一部分(O(NlogN))
见归并排序 - 二分策略:一个事情从中间划分两部分,根据条件判断只需要执行其中的一部分(O(logN))
见二分查找
空间复杂度
一个程序的空间复杂度是指运行完一个程序所需内存的大小。
(1) 固定部分。这部分空间的大小与输入/输出的数据的个数多少、数值无关。主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间。这部分属于静态空间。
(2) 可变空间,这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等。这部分的空间大小与算法有关。
具体看堆栈部分