数据结构浅析(二):算法

一、前言

我们常常会看到《数据结构与算法》之类的书,那么数据结构和算法为什么会在一起呢?通过上一篇 数据结构基本概念 我们知道,数据结构是互相之间存在一种或多种特定关系的数据元素的集合。这里的 一种或多种特定关系的处理就涉及到算法,所以对于完整的程序设计 数据结构算法 都很重要。

本篇主要介绍算法的一些概念内容,方便后面的数据结构学习。

二、什么是算法?

算法(Algorithm) 英文词最早是由 9 世纪 波斯数学家花拉子米 提出,欧几里得算法被人们认为是史上第一个算法。如今普遍对算法的定义是:算法是决定特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。

简而言之也就是为了解决某个或某类问题,需要把指令表示成一定的操作序列,操作序列包括一组操作,每一个操作都完成特定的功能,这就是算法了。

三、算法的特征

算法具有五个基本特征:输入输出有穷性确定性可行性

前面三个从字面很容易理解,简单说下后面两个;
确定性 指算法在一定确定条件下,相同的输入只可能有唯一的输出结果;
可行性 指算法的每一步都可以通过执行有限次数完成。

四、算法设计的要求

好算法的基本要求有:正确性可读性健壮性时间效率高和存储量低

4.1、正确性

算法的正确性指算法至少具有输入、输出、加工处理无歧义、能正确反映问题需求、能得倒问题的正确答案。
具体到程序大体分为下面 4 个层次:

  • 算法程序没有语法错误;
  • 算法程序对于合法的输入数据能够产生满足要求的输出结果;
  • 算法程序对于非法的输入数据能够得出满足规格说明的结果;
  • 算法程序对于极端的测试数据都有满足要求的输出结果。

证明一个复杂算法正确性代价很高,很难通过程序证明,一般采用数学方法证明,满足前 3 个层次就可以说是一个合格的算法了。

4.2、可读性

程序设计很多时候不是一个人搞定的,便于阅读理解还是很重要的。

4.3、健壮性

当输入数据不合法时,算法能做出相关处理,而不是产生异常或莫名其妙的结果,那么这就是健壮的算法。

4.4、时间效率高和存储量低

时间效率高是相对的。对于同一个问题,如果有多个算法可以解决,执行时间短的就是效率高的;

存储量指的是算法在执行过程中需要的最大内存和外部硬盘存储空间。我们生活中中希望花最少的钞票、最少的时间办最大的事,算法也是如此。

五、算法时间复杂度

5.1、什么是算法时间复杂度?

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

n 表示问题规模;T ( n ) 表示语句总的执行次数;f ( n ) 是问题规模 n 的某个函数;大 O ( ) 用来记录算法时间复杂度,如我们常见的 O ( 1 )、O ( n ) 、O ( n^2 ) ....

一般情况下,随着 n 的增大, T ( n ) 增长最慢的算法为最优算法

5.2、怎么分析出算法的时间复杂度?

如何分析出一个算法的时间复杂度呢?这里有个分析时间复杂度的推导方法

  • 用常数 1 取代运行时间中的所有加法常数;
  • 在修改后的运行次数函数中,只保留最高阶项;
  • 如最高阶项存在且不是 1 ,则去除与这个项相乘的常数。

下面分析一些简单的算法时间复杂度。

5.3、常数阶

例如:求 1+2+3+...+100 和
我们很容易想到的是 高斯算法,如下:

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

T ( n ) = O ( f ( n ) ),找到依次数据,很容易得到 f ( n ) = 3;根据上面给出的推到方法,我们很容易得出 高斯算法 的时间复杂度为O (1)

5.4、线性阶

举个例子,如下:

for (i = 0; i < n; i++ )
{
  /* 时间复杂度为 O (1) 的程序步骤序列 */
}

循环体中的代码需要执行 n 次,即 f( n ) = n,所以它的时间复杂度为 O( n )

5.5、对数阶

举例如下:

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

每次 count * 2 之后,就距离 n 更近一分。那么有多少个 2 相乘后大于 n 退出循环? 数学表示来看也就是 2^x = n ,得到 x = log(2 为底 n 的对数) [markdown 写数学公式功底不够,理解就好...],得出 T( n ) = logn;

5.6、平方阶

下面是一个循环嵌套例子:

int i, j;
for (i = 0; i< n; i ++)
{
    for (j = 0; j < n; j++)
    {
        /* 时间复杂度为 O(1) 的程序步骤序列 */
    }
}

外层内层的时间复杂度都是 O(n),所以这段代码的时间复杂度是 O(n^2).

再看下面一个循环嵌套例子:

int i, j;
for (i = 0; i< m; i ++)
{
    for (j = 0; j < n; j++)
    {
        /* 时间复杂度为 O(1) 的程序步骤序列 */
    }
}

外层和内层的时间复杂度依次为 O(m), O(n),所以这段代码的时间复杂度是 O(m * n)

接着再看一个例子:

int i, j;
for (i = 0; i < n; i++)
{
   for (j = i; j < n; j++)
    {
        /* 时间复杂度为 O(1) 的程序步骤序列*/
    }
}

当 i = 0 时,内循环执行 n 次;当 i = 1 时,内循环执行 n-1 次;......;当 i = n -1时,执行 1 次。所以总的执行次数为:

n + (n - 1) + (n - 2) + ... + 1 = n(n + 1) / 2 = n^2 / 2 + n / 2

根据前面的推导方法,很容易得到这段代码的时间复杂度O(n^2).

5.7、常见时间复杂度

常见时间复杂度如表:

执行次数 函数阶 非正式术语
12 O(1) 常数阶
2n + 3 O(n) 线性阶
3n^2 + 2n + 1 O(n^2) 平方阶
6n^3 + 2n^2 + 3n +4 O(n^3) 立方阶
5log2n + 20 O(logn) 对数阶
2n + 3nlog2n + 19 O(nlogn) nlogn 阶
2^n O(2^n) 指数阶

常用时间复杂度所消耗时间从小到大依次为:

O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

# 其中的 指数阶 和 阶乘阶 很少用到,你懂的...

六、算法空间复杂度

算法的空间复杂度通过计算算法所需的存储空间实现,计算公式: S(n) = O( f( n ) )n 为问题的规模,f(n) 为语句关于 n 所占存储空间的函数。

通常,我们使用时间复杂度来指运行时间的需求,用空间复杂度指空间需求。

七、总结

本篇提到的算法时间复杂度用处还是挺多的,后面自己写程序过程中也尽可能得降低时间复杂度。

本篇参考:

大话数据结构
Wikipedia - 算法(Algorithm)

戳这里 前往我的小屋:I'm Jony

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

推荐阅读更多精彩内容