`

算法时间复杂度分析基础

 
阅读更多
摘要
      本文论述了在算法分析领域一个重要问题——时间复杂度分析的基础内容。本文将首先明确时间复杂度的意义,而后以形式化方式论述其在数学上的定义及相关推导。从而帮助大家从本质上认清这个概念。

前言
      通常,对于一个给定的算法,我们要做 两项分析。第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式、数学归纳法等。而在证明算法是正确的基础上,第二部就是分析算法的时间复杂度。算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大程度上能很好反映出算法的优劣与否。因此,作为程序员,掌握基本的算法时间复杂度分析方法是很有必要的。
      但是很多朋友并不能清晰的理解这一概念,究其原因,主要是因为没有从数学层面上理解其本质,而是习惯于从直观理解。下面,我们就一步步走近算法时间复杂度的数学本质。

http://www.cnblogs.com/leoo2sk/archive/2008/11/14/1332381.html

算法时间复杂度的数学意义
      从数学上定义,给定算法A,如果存在函数F(n),当n=k时,F(k)表示算法A在输入规模为k的情况下的运行时间,则称F(n)为算法A的时间复杂度。
      这里我们首先要明确输入规模的概念。关于输入规模,不是很好下定义,非严格的讲,输入规模是指算法A所接受输入的自然独立体的大小。例如,对于排序算法来说,输入规模一般就是待排序元素的个数,而对于求两个同型方阵乘积的算法,输入规模可以看作是单个方阵的维数。为了简单起见,在下面的讨论中,我们总是假设算法的输入规模是用大于零的整数表示的,即n=1,2,3,……,k,……
      我们还知道,对于同一个算法,每次执行的时间不仅取决于输入规模,还取决于输入的特性和具体的硬件环境在某次执行时的状态。所以想要得到一个统一精确的F(n)是不可能的。为了解决这个问题,我们做一下两个说明:
      1.忽略硬件及环境因素,假设每次执行时硬件条件和环境条件是完全一致的。
      2.对于输入特性的差异,我们将从数学上进行精确分析并带入函数解析式。

算法时间复杂度分析示例
      为了便于朋友们理解,我将不会采用教科书上惯用的快速排序、合并排序等经典示例进行分析,而是使用一个十分简单的算法作为示例。我们先来定义问题。
      问题定义:
      输入——此问题输入为一个有序序列,其元素个数为n,n为大于零的整数。序列中的元素为从1到n这n个整数,但其顺序为完全随机。
      输出——元素n所在的位置。(第一个元素位置为1)

      这个问题非常简单,下面直接给出其解决算法之一(伪代码):

      LocationN(A)
      {
            for(int i=1;i<=n;i++)-----------------------t1
            {
                  if(A[i] == n) ----------------------------t2
                        { return i; }------------------------t3
            }
      }

      我们来看看这个算法。其中t1、t2和t3分别表示此行代码执行一次需要的时间。
      首先,输入规模n是影响算法执行时间的因素之一。在n固定的情况下,不同的输入序列也会影响其执行时间。最好情况下,n就排在序列的第一个位置,那么此时的运行时间为“t1+t2+t3”。最坏情况下,n排在序列最后一位,则运行时间为“n*t1+n*t2+t3=(t1+t2)*n+t3”。可以看到,最好情况下运行时间是一个常数,而最坏情况下运行时间是输入规模的线性函数。那么,平均情况如何呢?
      问题定义说输入序列完全随机,即n出现在1...n这n个位置上是等可能的,即概率均为1/n。而平均情况下的执行次数即为执行次数的数学期望,其解为:

      E
      = p(n=1)*1+p(n=2)*2+...+p(n=n)*n
      = (1/n)*(1+2+...+n)
      = (1/n)*((n/2)*(1+n))
      = (n+1)/2

      即在平均情况下for循环要执行(n+1)/2次,则平均运行时间为“(t1+t2)*(n+1)/2+t3”。
      由此我们得出分析结论:
      t1+t2+t3 <= F(n) <= (t1+t2)*n+t3,在平均情况下F(n) = (t1+t2)*(n+1)/2+t3

算法的渐近时间复杂度
      以上分析,我们对算法的时间复杂度F(n)进行了精确分析。但是,很多时候,我们不需要进行如此精确的分析,原因有下:
      1.在较复杂的算法中,进行精确分析是非常复杂的。
      2.实际上,大多数时候我们并不关心F(n)的精确度量,而只是关心其量级。
      基于此,提出渐近时间复杂度的概念。在正式给出渐近时间复杂度之前,要先给出几个数学定义:

      定义一:Θ(g(n))={f(n) | 如果存在正常数c1、c2和正整数n0,使得当n>=n0时,0<c1g(n)<=f(n)<=c2g(n)恒成立}
      定义二:Ο(g(n))={f(n) | 如果存在正常数c和正整数n0,使得当n>=n0时,0<=f(n)<=cg(n)恒成立}
      定义三:Ω(g(n))={f(n) | 如果存在正常数c和正整数n0,使得当n>=n0时,0<=cg(n)<=f(n)恒成立}

      可以看到,三个定义其实都定义了一个函数集合,只不过集合中的函数需要满足的条件不同。有了以上定义,就可以定义渐近时间复杂度了。
      不过这里还有个问题:F(n)不是确定的,他是在一个范围内变动的,那么我们关心哪个F(n)呢?一般我们在分析算法时,使用最坏情况下的F(n)来评价算法效率,原因有如下两点:
      1.如果知道了最坏情况,我们就可以保证算法在任何时候都不能比这个情况更坏了。
      2.很多时候,算法运行发生最坏情况的概率还是很大的,如查找问题中待查元素不存在的情况。且在很多时候,平均情况的渐近时间复杂度和最坏情况的渐近时间复杂度是一个量级的。

      于是给出如下定义:设F(n)为算法A在最坏情况下F(n),则如果F(n)属于Θ(g(n)),则说算法A的渐近时间复杂度为g(n),且g(n)为F(n)的渐近确界。

      还是以上面的例子为例,则在上面定义中F(n) = (t1+t2)*n+t3。则F(n)的渐近确界为n,其证明如下:

      证明:
      设c1=t1+t2,c2=t1+t2+t3,n0=2
      又因为 t1,t2,t3均大于0
      则,当n>n0时,0<c1n<=F(n)<=c2n 即 0<(t1+t2)*n<=(t1+t2)*n+t3<=(t1+t2+t3)*n恒成立。
      所以 F(n)属于Θ(n)
      所以 n是F(n)的渐近确界
      证毕

      在实际应用中,我们一般都是使用渐近时间复杂度代替实际时间复杂度来进行算法效率分析。一般认为,一个渐近复杂度为n的算法要优于渐近复杂度为n^2的算法。注意,这并不是说渐近复杂度为n的算法在任何情况下都一定更高效,而是说在输入规模足够大后(大于临界条件n0),则前一个算法的最坏情况总是好于后一个算法的最坏情况。事实证明,在实践中这种分析是合理且有效的。
      类似的,还可以给出算法时间复杂度的上确界和下确界 :
      设F(n)为算法A在最坏情况下F(n),则如果F(n)属于Ο(g(n)),则说算法A的渐近时间复杂度上限为g(n),且g(n)为F(n)的渐近上确界。
      设F(n)为算法A在最坏情况下F(n),则如果F(n)属于Ω(g(n)),则说算法A的渐近时间复杂度下限为g(n),且g(n)为F(n)的渐近下确界。
      这里一定要注意,由于我们是以F(n)最坏情况分析的,所以,我们可以100%保证在输入规模超过临界条件n0时,算法的运行时间一定不会高于渐近上确界,但是并不能100%保证算法运行时间不会低于渐近下确界,而只能100%保证算法的最坏运行时间不会低于渐近下确界。

总结
      算法时间复杂度分析是一个很重要的问题,任何一个程序员都应该熟练掌握其概念和基本方法,而且要善于从数学层面上探寻其本质,才能准确理解其内涵。在以上分析中,我们只讨论了“紧确界”,其实在实际中渐近确界还分为“紧确界”和“非紧确界”,有兴趣的朋友可以查阅相关资料。
      好了,本文就到这里了,希望本文内容能对各位有所帮助。
分享到:
评论

相关推荐

    算法时间复杂度分析基础 (论文)

    "算法时间复杂度分析基础" 本文论述了算法时间复杂度分析的基础内容,涵盖了时间复杂度的定义、数学意义、分析示例等方面的知识点。 时间复杂度是指算法执行时间随输入规模增长而增长的量级,是评价算法优劣的重要...

    算法复杂度分析基础课件

    《算法复杂度分析基础》 算法复杂度分析是评估算法效率的重要工具,主要涉及时间复杂度和空间复杂度两个方面。这门基础课程旨在教授如何分析算法在处理大规模数据时所需的资源,帮助开发者优化程序性能。 一、算法...

    排序算法时间复杂度的研究.pdf

    ### 排序算法时间复杂度的研究 #### 引言 排序是计算机科学中的基础操作之一,主要用于对数据集中的元素按照特定的顺序进行排列。排序算法的效率直接关系到计算机程序的整体性能。根据数据是否完全加载到内存中,...

    分析算法时间复杂度java.zip

    在这个"分析算法时间复杂度java.zip"文件中,我们可以预期包含的是关于如何在Java中分析和理解各种算法时间复杂度的相关资源,比如数据结构的实现及其时间复杂度分析。 数据结构是存储和组织数据的特定方式,它们对...

    算法实验代码和报告(时间复杂度、0-1背包问题、分治与贪心、蛮力法)

    本资源包含的“算法实验代码和报告”聚焦于几个重要的算法概念:时间复杂度、0-1背包问题、分治策略以及贪心方法,这些都是计算机科学中基础且实用的知识点。 首先,我们来看**时间复杂度**。时间复杂度是用来衡量...

    排序算法的时间复杂度分析

    本项目通过对选择排序法进行时间复杂度分析,来探讨其性能特点。 选择排序是一种基础的排序算法,它的基本思想是在未排序的序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续...

    NOIP普及组 提高组 CSP-J CSP-S初赛 算法的时间复杂度部分题目.pdf

    算法时间复杂度的相关知识点 从给定的文件信息中,我们可以看到该文件主要关注算法的时间复杂度,涉及到算法设计、递归式、主定理等概念。下面,我们将对这些知识点进行详细的解释和分析。 一、算法时间复杂度 ...

    算法-数据结构和算法-1-算法的引入和算法时间复杂度.rar

    这个压缩包文件"算法-数据结构和算法-1-算法的引入和算法时间复杂度.rar"主要探讨了这两个概念的入门知识,特别是关注算法的时间复杂度分析。 首先,我们需要理解什么是算法。算法是一系列明确的步骤或指令,用于...

    C++矩阵连乘源代码和题目描述和算法复杂度的解析

    动态规划能降低算法的时间复杂度,避免不必要的重复计算,尤其是在处理大矩阵时,效果尤为显著。 矩阵连乘的动态规划解决方案通常基于斯特恩-布鲁克定理,它可以将矩阵连乘的问题转化为更小规模的子问题。我们可以...

    NOIP普及组 提高组 CSP-J CSP-S初赛 算法的时间复杂度部分题目(2023.09.15)C.pdf

    本题集主要涉及了NOIP(全国青少年信息学奥林匹克竞赛)普及组和提高组的CSP-J(Junior)和CSP-S(Senior)初赛中的算法时间复杂度题目,涵盖了不同类型的算法和时间复杂度分析。 1. **稳定性**: - 在排序算法中...

    算法复杂度原理

    1. 时间复杂度:时间复杂度是描述算法运行过程中基本操作的执行次数。常用的大O记法表示,如O(1)、O(logn)、O(n)、O(nlogn)、O(n^2)等,分别代表常数时间、对数时间、线性时间、线性对数时间和平方时间。理解这些...

    算法设计与优化中的时间复杂度分析

    使用场景及目标:适用于需要深入理解算法性能分析的人群,通过学习时间复杂度的相关知识,能够更有效地评估和优化算法。 阅读建议:本文不仅提供理论知识,还包含了具体的算法实例,建议在阅读时结合实际代码进行...

    信息学奥赛算法时间复杂度和空间复杂度计算

    算法效率分析主要包括时间效率和空间效率,它们分别对应于时间复杂度和空间复杂度的概念。 首先,时间效率指的是算法在解决问题时所消耗的时间,用时间复杂度来衡量。时间复杂度是对算法运行时间随问题规模增长的...

    排序算法时间复杂度的研究

    ### 排序算法时间复杂度的研究 #### 引言 排序是计算机科学中的基础操作之一,在数据处理与分析中占据着重要地位。排序算法的好坏直接影响到计算机程序的执行效率,尤其是在处理大规模数据集时更为明显。根据数据...

    时间复杂度的几种计算方法

    假设对于给定的算法,目前问题规模为n,则语句频度可以表示成一个关于问题规模的函数T(n),那么算法时间复杂度也就可以用T(n)表示,其含义是算法在输入规模为n时的运行时间。 渐进时间复杂度是时间性能分析的依据,...

    算法设计与分析基础.第3版

    10. **时间复杂度与空间复杂度**:分析算法效率的关键工具,书中详细阐述了如何计算和比较不同算法的时间复杂度和空间复杂度,以及大O记法。 11. **概率算法和随机化算法**:利用随机性和概率理论设计算法,如Monte...

    算法设计与分析基础第三版答案

    《算法设计与分析基础》是计算机科学领域的一本经典教材,主要探讨了如何设计和评估算法,以及如何通过数学分析来理解算法的效率。这本书的第三版提供了更深入的算法讲解,涵盖了各种基本的和高级的算法技术。针对你...

    算法复杂度作业2

    - 时间复杂度:表示算法执行过程中基本操作的数量与输入数据规模的关系,通常用大O记法表示,如O(1),O(n),O(n log n)等。 - 空间复杂度:衡量算法运行时所需的内存空间,同样使用大O记法来描述。 2. **Shell**...

    算法设计与分析基础课后习题答案(中文版).doc

    本资源摘要信息涵盖了算法设计与分析基础课后习题答案的主要知识点,涵盖了算法设计与分析的基础概念、欧几里得算法、平方根算法、二进制转换算法、数组操作算法、时间复杂度分析等。 1. 欧几里得算法 欧几里得...

Global site tag (gtag.js) - Google Analytics