数据结构和算法之时间复杂度和空间复杂度

前言

上一篇《数据结构和算法》中我介绍了数据结构的基本概念,也介绍了数据结构通常能够分为逻辑结构和物理结构。逻辑结构分为集合结构、线性结构、树形结构和图形结构。物理结构分为顺序存储结构和链式存储结构。而且也介绍了这些结构的特色。而后,又介绍了算法的概念和算法的5个基本特性,分别是输入、输出、有穷性、肯定性和可行性。最后说阐述了一个好的算法须要遵照正确性、可读性、健壮性、时间效率高和存储量低。其实,实现效率和存储量就是时间复杂度和空间复杂度。本篇咱们就围绕这两个"复杂度"展开说明。在真正的开发中,时间复杂度尤其重要,空间复杂度咱们不作太多说明。算法

时间复杂度

时间复杂度和空间复杂度是算法效率的度量方法。也就是说,一个好的算法取决于它的时间复杂度和空间复杂度。

函数的渐近增加:给定两个函数f(n)和g(n),若是存在一个整数N,使得对于全部的n>N,f(n)老是比g(n)大。那么,咱们说f(n)的增加渐近快于g(n)。数据结构

翻译过来就是:若是存在一个临界值,使得f(n)>g(n)永远成立,那么咱们就认为"f(n)的增加渐近快于g(n)"。数据结构和算法

这里我拿3个函数的增加曲线来讲明问题。以下图:函数

函数一:X = 3*n spa

函数二:Y = 2*n*n翻译

函数三:Z = 2*n*n+3*ncode

当n=1时,Y < X < Z.blog

当n=2时,X < Y < Z.图片

因此,存在一个值,这个值位于1和2之间,使得X < Y < Z永远成立。咱们就称Y的渐进增加快于X,Z的渐进增加快于Y,固然,根据传递性规则,Z的渐进增加也快于X。内存

定义

算法时间复杂度的定义:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化状况并肯定T(n)的数量级。

算法的时间复杂度,也就是算法的时间量度,记做:T(n)= O(f(n))。

它表示随问题规模n的增大,算法执行时间的增加率和f(n)的增加率相同,称做算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。

时间复杂度计算方法

1.用常数1取代运行时间中的全部加法常数。

2.在修改后的运行次数函数中,只保留最高阶项。

3.若是最高阶项存在且不是1,则去除与这个项相乘的常数。

最后,获得的最后结果就是时间复杂度。

常见的时间复杂度

按数量级递增排列,常见的时间复杂度有:
常数阶O(1),对数阶O( log n ),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n^2),立方阶O(n^3),...,k次方阶O(n^k),指数阶O(2^n)。随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低。
也就是:
经常使用的时间复杂度所耗费的时间从小到大依次是: O(1) < O(logn) < (n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

常数阶

// 常数阶
int n = 0;
printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”); printf(“oneSong”);

上面这段代码的时间复杂度是O(1)。由于,按照时间复杂度的定义来讲,n和问题的规模没有关系。固然,按照时间复杂度计算方法第一条也能够得出结果为O(1)。

线性阶

 
// 线性阶
int i , n = 10086, sum = 0;
 
for( i=0; i < n; i++ )
{
    sum = sum + i;
}

上面这段代码的时间复杂度是O(n),由于问题规模会随着n的增加而变得愈来愈大,而且这种增加是线性的。

平方阶

// 平方阶
int i, j, n = 998;
 
for( i=0; i < n; i++ )
{
    for( j=0; j < n; j++ )
    {
        printf(“oneSong”);
    
}

上面这段代码外层执行n次,外层循环每执行一次,内层循环就执行n次,那总共程序想要从这两个循环出来,须要执行n*n次,也就是n的平方。因此这段代码的时间复杂度为O(n^2)。

对数阶

// 对数阶
int i = 1, n = 100;
 
while( i < n )
{
    i = i * 2;
}

因为每次i*2以后,就距离n更近一步,假设有x个2相乘后大于或等于n,则会退出循环。因而由2^x = n获得x = log(2)n,因此这个循环的时间复杂度为O(logn)。

算法的空间复杂度

算法的空间复杂度经过计算算法所需的存储空间实现,算法的空间复杂度的计算公式记做:S(n)=O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。
在 程序开发中,咱们所指的复杂度不作特别说明的状况下,就是指时间复杂度。如今的硬件发展速度之快使得咱们彻底能够不用考虑算法所占的内存,一般都是用空间 换取时间。加之算法的空间复杂度比较难算,因此,不管是在考试中仍是在项目开发中,咱们都侧重于时间复杂度。因此,空间复杂度,略过。

图片来源参考自:鱼C工做室。感谢鱼C工做室贡献出了这么好的图片。
如非特别说明,笔者全部文章都是原创文章。若是您喜欢这篇文章,转载请注明出处。若是您对数据结构感兴趣,请关注我,后续会更新大量精品文章供你们参考!

PS:本篇文章在简书也有同步更新,你们也能够移步简书关注本人,后续会更新更多精品文章!

简书地址:http://www.jianshu.com/users/93131dfba96a/latest_articles

相关文章
相关标签/搜索