空间复杂度概念
算法的空间复杂度通过计算算法所需的存储空间实现,算法的空间复杂度的计算公式记作:S(n)=O(f(n)),n 为问题的规模,f(n) 为语句关于 n 所占存储空间的函数
算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源,因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量,即时间复杂度和空间复杂度
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小,所以对空间的复杂度很在乎,经过计算机行业的迅速发展,计算机的存储容量已经达到很高的程度,已经不需要再特别关注一个算法的空间复杂度了
时间复杂度的概念
算法的时间复杂度,在进行算法分析时,语句总的执行次数 T(n) 是关于问题规模 n 的函数,分析 T(n) 随 n 的变化情况并确定 T(n) 的数量级,算法的时间复杂度,也就是算法的时间量度,记作:T(n) = O(f(n)) 表示随问题规模 n 的增大,算法执行时间的增长率和 f(n) 的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度,其中 f(n) 是问题规模 n 的某个函数
时间复杂度的定义:在计算机科学中,算法的时间复杂度是函数数
它定量描述了该算法的运行时间,一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式,一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
大写 O() 来体现算法时间复杂度,一般情况下随着输入规模 n 的增大,T(n)增长最慢的算法为最优算法三个求和的算法时间复杂度为 O(1) , O(n) , O(n^2) 其中 O(1) 为最优算法,因为始终只有 1 次运算
推导大O阶的方法
用常数 1 取代运行时间中的所有加法常数
在修改后的运行次数函数中,只保留最高阶项
如果最高阶存在且不是 1 ,则去除与这个项相乘的常数 假设O(n^3) 则把 3 去掉剩下 O(n^)
得到最后结果就是大 O 阶
函数调用的时间复杂度分析
函数体打印参数, functon 函数的时间复杂度是 O(1) , 所以整体的时间复杂度就是循环的次数 O(n)
void main(){
int i ;
for(i = 0 ; i < n; i++){
function(i);
}
}
void function(int count){
printf("%d",count);
}function 内部循环次数随 count 增加(接近n)而减少,算法时间复杂度为O(n^2)
void main(){
int i ;
for(i = 0; i < n; i++){
function(i);
}
}
void function(int count){
int j;
for(j = count ; j < n; j++){
printf("%d",j);
}
}常见的时间复杂度
常用的时间复杂度所耗费的时间从小到大依次是:O(1) < O(logn) < (n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
算法效率的度量方法
事后统计方法:
这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。
这种方法有很大缺陷:
必须依据算法事先编制好测试程序,通常需要花费大量时间和精力,完了发觉测试的是糟糕的算法,
不同测试环境差别很大
事前分析估算方法:
在计算机程序编写前,依据统计方法对算法进行估算。
高级语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:
1.算法采用的策略,方案
2.编译产生的代码质量
3.问题的输入规模
4.机器执行指令的速度
由此可见,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间依赖于算法的好坏和
问题的输入规模。(输入规模是指输入量的多少)