对于数据结构的基本概念我们不做叙述,本节重点讨论算法效率的度量。
性能分析的角度
一般我们从时间复杂度和空间复杂度两个方面对算法的效率进行分析。
一.时间复杂度(Time Complexity)
我们通常将时间复杂度记为:
T(n)=O(f(n))
我们将此式分为三个部分进行讲述。
- T(n):算法的渐近时间复杂度,简称时间复杂度。
- f(n):算法中语句中执行次数最多的语句的频度。
- O():计算数量级。
数学表达式为:
存在正常数C和n0,当n>=n0时,0<=T(n)<=C*f(n)
1.三种时间复杂度
- 最坏时间复杂度:最坏情况下的时间复杂度。
- 平均时间复杂度:所有输入实例等概率出现情况。
- 最好时间复杂度:最好情况下时间复杂度。
我们利用一个例子说明:
在冒泡排序中,如果序列本有序,我们只需比较n-1次,排序完成,则为最好情况下时间复杂度为O(n)。如果序列为逆序,则需要比较(n-1)+(n-2)+....+1=n*(n-1)/2,此时时间复杂度为O(n²)。则平均复杂的也为O(n²)。
2.常见的时间复杂度(从小到大排列)
- 常数阶:O(1)
- 对数阶:O(log2n)
void fun(int n){
int i=1;
while(i<=n)
i=i*2;
}
- 线性阶:O(n)
for(int i=0;i++;i<n)
- 线性对数阶:O(nlog2n)
count=0;
for(k=1;k<=n;k*=2)
for(j=1;j<=n;j++)
count++;
- 平方阶:O(n²)
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
}
- 立方阶:O(n³)
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++)
}
}
- 指数阶:O(2^n)
//Fibonacci数列的递归算法
int f(int n){
if(n==1||n==0){
return 1;
}
return f(n-1)+f(n-2);
}
- 阶乘:O(n!)
- k次方阶:O(n^k)
3.时间复杂度的计算
- 循环条件中变量参与循环条件
int i=1;
while(i<=n){
i=i*2;
}
对于此种程序,我们设循环次数为t,则可根据循环条件得到:
2^t<=n 于是可以推出 t<=log2n,得到T(n)=log2n
- 循环主体中变量与循环条件无关
Ⅰ.递归程序:利用公式进行递推。
Ⅱ.非递归程序
二.空间复杂度(Space Complexity)
我们通常将空间复杂度记为:
S(n)=O(f(n))
我们将此式分为三个部分进行讲述。
- S(n):空间复杂度。
- f(n):辅助存储空间。
辅助存储空间:
一般情况下, 一个程序在机器上执行时, 除了需要存储本身所需要的代码/输入数据外, 还需要一些对数据进行操作的辅助存储空间.其中输入数据所占用的具体空间取决于问题本身, 与算法无关. 因此我们所讨论的空间复杂度只与该算法在实现时所需要的辅助空间单元个数相关
- O():数量级。
1.常见空间复杂度
- 常数阶 O(1):冒泡排序,直接插入排序,简单选择排序,希尔排序,堆排序。
- 线性阶 O(n):二路归并排序。
- 对数阶 O(log2n):快速排序。
author by HengGeZhiZou