算法时间复杂度&空间复杂度(附github)

(*useful)标记:目前觉得有用的函数
//FIXME 标记:待补充

基本初等函数:

  • 幂函数:

一般地,形如y=xα(α为有理数)的函数,即以底数自变量,幂为因变量指数为常数的函数称为幂函数。例如函数y=x0 、y=x1、y=x2、y=x-1(注:y=x-1=1/x y=x0时x≠0)等都是幂函数。一般形式如下:


( α为常数,且可以是自然数、有理数,也可以是任意实数复数。)
有理数: (正整数、0、负整数)和(正分数,负分数)的统称

  • 指数函数:

指数函数是数学中重要的函数。应用到值e上的这个函数写为exp(x)。还可以等价的写为ex,这里的e是数学常数,就是自然对数的底数,近似等于 2.718281828,还称为欧拉数。一般形式如下:


指数函数

(a>0, a≠1),所以指数函数处于一二象限

  • 对数函数:

一般地,函数y=logax(a>0,且a≠1)叫做对数函数,也就是说以真数)为自变量,指数为因变量,底数为常量的函数,叫对数函数。

其中x是自变量,函数的定义域是(0,+∞),即x>0。它实际上就是指数函数反函数,可表示为x=ay。因此指数函 数里对于a的规定,同样适用于对数函数。一般形式如下:

(a>0, a≠1, x>0,特别当α=e时,记为y=ln x)

时间复杂度

(一)时间频度

一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。
一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。

(二)时间复杂度

在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度 ,简称时间复杂度。

符号OLandau符号的作用在于用简单的函数来描述复杂函数行为,给出一个上或下(确)界:
某个算法的时间复杂度是 O(1), 常数阶, 优秀
某个算法的时间复杂度是 O(log2 n),对数阶, 良好
某个算法的时间复杂度是 O(n), 线性.次线性阶,还好
某个算法的时间复杂度是 O(n log2 n),线性对数阶, 还不错
某个算法的时间复杂度是 O(n2), 平方阶, 差一些
(*useful)

(三)求解算法的时间复杂度的具体步骤是

(1) 找出算法中的基本语句;
  算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体。
(2) 计算基本语句的执行次数的数量级;
  只需计算基本语句执行次数的数量级,这就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂和最高次幂的系数。这样能够简化算法分析,并且使注意力集中在最重要的一点上:增长率。
(3)用大Ο记号表示算法的时间性能。
  将基本语句执行次数的数量级放入大Ο记号中。

如果算法中包含嵌套的循环,则基本语句通常是最内层的循环体,如果算法中包含并列的循环,则将并列循环的时间复杂度相加。例如:

  for (i=1; i<=n; i++) {
        x++;  
  }
  for (i=1; i<=n; i++)  {
      for (j=1; j<=n; j++)  {
            x++;  
      }
}

第一个for循环的时间复杂度为Ο(n),第二个for循环的时间复杂度为Ο(n2),则整个算法的时间复杂度为Ο(n+n2)=Ο(n2)。

(*useful)
Ο(1): 表示基本语句的执行次数是一个常数,一般来说,只要算法中不存在循环语句,其时间复杂度就是Ο(1)。
多项式时间: O(log2n)、Ο(n)、 Ο(n log2n)、Ο(n2)和Ο(n3) 。 (推荐)
指数时间: Ο(2n)和Ο(n!) 。

(四)下面分别对几个常见的时间复杂度进行示例说明

(1)、O(1)

        Temp=i; i=j; j=temp;        

以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。算法的时间复杂度为常数阶,记作T(n)=O(1)。注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。

(2)、O(n2)

2.1. 交换i和j的内容

 sum=0;                 (一次)  
 for(i=1;i<=n;i++)     (n+1次)  
     for(j=1;j<=n;j++) (n2次)  
         sum++;            (n2次)  

解:因为Θ(2n2+n+1)=n2(Θ即:去低阶项,去掉常数项,去掉高阶项的常参得到),所以T(n)= =O(n2);

2.2.

 for (i=1;i<n;i++)  
  {   
      y=y+1;         ①     
      for (j=0;j<=(2*n);j++)      
            x++;         ②        
  }            

解:
语句1的频度是n-1
语句2的频度是(n-1)(2n+1) = 2n2-n-1
f(n)=2
n2-n-1+(n-1) = 2n2-2;

Θ(2n2-2)=n2
该程序的时间复杂度T(n)=O(n2).

一般情况下,对步进循环语句只需考虑循环体中语句的执行次数,忽略该语句中步长加1、终值判别、控制转移等成分,当有若干个循环语句时,算法的时间复杂度是由嵌套层数最多的循环语句中最内层语句的频度f(n)决定的。

(3)、O(n)

  a=0;  
    b=1;                      ①  
      for (i=1;i<=n;i++) ②  
      {    
        s=a+b;    ③  
        b=a;     ④    
        a=s;     ⑤  
     }  

解: 语句1的频度:2,
语句2的频度: n,
语句3的频度: n-1,
语句4的频度:n-1,
语句5的频度:n-1,
T(n)=2+n+3(n-1)=4n-1=O(n).

(4)、O(log2n)

  i=1;     ①  
  while (i<=n)  
      i=i*2; ②  

解: 语句1的频度是1,
设语句2的频度是f(n), 则:2^f(n)<=n;f(n)<=log2n
取最大值f(n)=log2n,
T(n)=O(log2n)

(5)、O(n3)

 for(i=0;i<n;i++)  
  {    
    for(j=0;j<i;j++)    
    {  
      for(k=0;k<j;k++)  
      x=x+2;    
    }  
  }  

解:当i=m, j=k的时候,内层循环的次数为k当i=m时, j 可以取 0,1,...,m-1 , 所以这里最内循环共进行了0+1+...+m-1=(m-1)m/2次所以,i从0取到n, 则循环共进行了:0+(1-1)1/2+...+(n-1)n/2=n(n+1)(n-1)/6
所以时间复杂度为O(n3).

(五)常用的算法的时间复杂度和空间复杂度

这里讨论的是内部排序

swift写的部分算法实现链接

算法时间复杂度分析是一个很重要的问题,任何一个程序员都应该熟练掌握其概念和基本方法,而且要善于从数学层面上探寻其本质,才能准确理解其内涵。

空间复杂度

类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度

空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。
一个算法在计算机存储器上所占用的存储空间,包括:

  1. 存储算法本身所占用的存储空间
    • 与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。
  2. 算法的输入输出数据所占用的存储空间
    • 由要解决的问题决定,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。
  3. 算法在运行过程中临时占用的存储空间
    • 随算法的不同而异,有的算法只需要占用少量的临时工作单元,而且不随问题规模的大小而改变,我们称这种算法是“就地"进行的,跟语言C,swift,js:对象开辟内存函数有关
    • 有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元

  • 当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);
  • 当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(log2n);
  • 当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n);
  • 若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;
  • 若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。

swift写的部分算法playground->github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容