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

<big>版权声明:本文为 Codeagles 原创文章,可以随意转载,但必须在明确位置注明出处!!!</big>

想要学会算法时间复杂度,那么就要先弄清楚几个概念。

  1. 什么是算法时间复杂度?
  2. 它有什么用呢?
  3. 写法记作 T(n)=O(f(n))
  • T(n):语句执行的总次数关于n的函数
  • n:问题规模
  • f(n):问题规模n的某个函数
  • 用O()来体现算法时间复杂度的记法

时间复杂度的定义是:如果一个问题的规模是n,解决这一问题所需算法所需要的时间是n的一个函数T(n),则T(n)称为这一算法的时间复杂度。
所谓算法时间复杂度就是一句话:算法中基本操作的执行次数。既然是T(n)的函数,随着模块n的增大,算法执行的时间的增长率和T(n)的增长率成正比,所以T(n)越小,算法的时间复杂度越低,算法的效率越高。

那么它有什么用呢?刚才也说了,可以通过f(n)的函数关系来评估算法的效率问题,说白了就是通过时间复杂度来看算法的好坏

值得注意的是:有的算法中基本操作执行次数不仅仅跟初始输入的数据规模(n)有关,还和数据本身有关。例如一些排序算法,同样n个待处理数据,数据初始有序性不同,基本操作执行次数也会不同。如果算法中有特殊要求,一般依照使得基本操作执行次数最多的输入来计算时间复杂度,即将最坏的情况最为算法时间复杂度的度量。

常见的是按复杂度的大小

常见的时间复杂度

有的人会对log2 n与log n做对比,不理解这里为什么不一样,其实这两个是一样的也就是图中第2个和第4个都是可以替换以2为底的对数形式。

对数时间
主条目:对数时间
若算法的T(n) = O(log n),则称其具有对数时间。由于计算机使用二进制的记数系统,对数常常以2为底(即log2 n,有时写作lg n)。然而,由对数的换底公式,loga n和logb n只有一个常数因子不同,这个因子在大O记法中被丢弃。因此记作O(log n),而不论对数的底是多少,是对数时间算法的标准记法。————维基

如何计算或者推导时间复杂度呢##

我们来分析一下常规做法:

  1. 确定算法中的基本操作以及问题的规模。
  2. 根据基本操作执行情况计算出规模n的函数f(n),并确定时间复杂度为T(n)=O( f(n)中增长最快的项/此项的系数 ).

那么是什么意思呢?记住这个利器,这三句话即可。

  1. 用常数1替换所有加法常数。
  2. 在修改后的运行次数的函数中,只保留最高阶项。
  3. 如果最高阶项不是1(例如O(1)),则把该项的系数除掉,得到O

开始实战##

这不是演戏,这不是演习,实战之后就可以完全掌握概念了。

第一类

看下面一对代码,进行分析:

int i=0,n=100;        /*执行了一次*/
i=n/2+n;              /*执行了一次*/
printf("i=%d",i);     /*执行了一次*/ 

那么不难分析出这段代码一共执行了3次,那么时间复杂度就是O(3),对吧?是不是很简单,如果真的是这样,那就错了,看我们的利器第一句,它是f(n)=3,所以应该把3改为1,即O(1)。那么看下面这个:

int i=0,n=100;        /*执行了一次*/
i=n/2+n;              /*执行了一次*/
printf("i=%d",i);     /*执行了一次*/ 
printf("i=%d",i);     /*执行了一次*/ 
printf("i=%d",i);     /*执行了一次*/ 
printf("i=%d",i);     /*执行了一次*/ 
printf("i=%d",i);     /*执行了一次*/ 

这段代码一共执行了7次,那么时间复杂度为多少呢,经过上面的坑,这个应该没问题了,对,f(n)=7,把7改为1,即O(1)。那么我们可以得知,这种代码是具有恒定的执行时间的,也就是代码不会因为问题规模n的变化而发生变化,所以我们都记为O(1).

第二类

void fun(int n)
{
    int i=1,j=100;
    while(i<n)
    {
        ++j;
        i+=2;
    }
}

这个显然n确定以后,循环的开始结束都是与i有关的,且每次自增2,假设m次后结束循环,那么i应该等于1+2m,那么就有n=1+2m,因为我们要是执行次数,也就是解得m=(n-1)/2,此时我们可以看出n/2增长的是最快的项,根据我们的法宝,我们需要把前面的系数除掉即可得到O,即(n/2)/(1/2)=n,得O(n).

有的为了更严谨的推导,会对上面的式子进行修改,即1+2m+K=n ,K为一个常数,因为循环的结束的时候往往i是稍稍大于n的,所以用一个K来修正这个式子,m=(n-1-K)/2,当然因为K为常数,所以不会影响最终结果,毕竟有一个增长更快的家伙把它的影响干掉了。

做到这,是不是感觉很简单了呢?那么我们趁热打铁进行下一个。

int i=1;
while(i<n)
{
    i=i*2;
}

推导时间复杂度,最重要的就是要分析算法的执行次数。那么这段程序怎么分析呢?试着自己分析一下,再来看吧。好啦,i起始值为1,每次都乘2,也就意味着每次都会距离n近一些,那么什么时候超过n而终止循环呢?很简单就是i22222...*2>n,那么假设k次之后大于n,就有2^k=n,得出k=logn(上面说了还有些log2 n,都是一样的,以后都写最简形。)
马上就要成功了,主要是练就分析算法和推导的思路。再来一个:

int i,j,x=0;
for(i=0;i<n;i++)
{
    for(j=0;j<n;j++)
        x++;
}

这段代码不用多想就知道,外循环执行n次,内循环也是执行n,则O(n^2).那么这段呢?

int i,j,x=0;
for(i=0;i<n;i++)
{
    for(j=i;j<n;j++)
        x++;
}

由于当i=0,时内循环执行了n次,i=1时,执行了n-1次,...i=n-1时,执行了1次,那么总次数为 n+(n-1)+(n-2)+..+1=n(n+1)/2,那么就是n2/2,即O(n2).

到这里基础的就结束了,我想大家也应该能看懂了吧,当然还有一些比较复杂的算法,大家可以去自行试试,对于该文章不懂得可以在文章下面留言,看到了我会回复的。

最后给大家做个练习吧。

i++;
function(n)  /* 方法function(n)为时间复杂度O(n)*/
int k,m;
while(k<n)
{
    function(n);
    k++;
}
for(k=0;k<n;k++)
{
    for(m=k;m<n;m++)
    {
        /*时间复杂度为O(1)的序列*/
    }
}

小试牛刀,检验成果吧,大家联系完这个,函数调用的时间复杂度也被你征服了,对于这个题可以在评论区留下你的答案,并和大家分享吧!

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

推荐阅读更多精彩内容