算法精解十八(C语言版)

计算的复杂度

        在谈到算法的性能时,我们通常关注的是它的复杂度,复杂度与它处理数据量所需要的资源(通常是时间)的增长速率密切相关。O表示法能够描述一个算法的复杂度。使用O表示法。通过观察算法的整体结构,我们很容易就可以描述最快的情况下的算法复杂度,有些时候,我们也会借助于利用迭代公式和统计方法(见本章结尾的相关主题)。

        为了理解复杂度,我们来看一种推测算法所用资源的方法。假设有一种算法,它由K条语句组成,每条语句都要消耗cj资源(通常是时间)。如果要计算它的整个运行时间,无论每条语句以什么顺序执行,我们只需要将它们的运行时间相加求和即可,也就是说从c1加到ck,通常每条语句并不是简单地按照循序执行的,所以计算整个运行时间时必须考虑其他更复杂的情况,例如:有些语句是在循序中执行的,那么这样一些语句所消耗的资源必须乘上迭代的次数。假设在这种算法中k=6,其中语句3~5均在循环中(1~n)执行,其他语句循序执行,那么此算法的整体运行时间表示为:


用O表示法的规则来计算,此算法的复杂度是O(n),因为可以忽略常熟项。用消耗固定资源的算法来分析问题是很透明的。然而,回顾之前谈到的增长速度,我们并不需要非常精确的结果。当观察一个算法的整体构造时,只需要做到两步:首先,必须知道算法的哪个部分是由非常量的数据决定的;然后,用函数列出每个部分的性能,那些消耗资源为常数项的部分在计算整个算法复杂度的过程中可以忽略。

在之前的例子中,假设T(n)表示算法的运行时间,我们必须明白,它的复杂度O(n)并没有具体表明运行此算法实际需要多少时间,换句话说,一个增长速率低的算法并不意味着它会消耗更少的运行时间。事实上,算法的复杂度并没有具体的计量单位。它只是表明当计算数据量的大小变化时,将如何影响算法所消耗的资源。例如:用O(n)表示T(n)复杂度只说明算法的大小变化时,将如何影响算法所消耗的资源。例如:用O(n)T(n)复杂度只说明算法的运行时间与因素n成正比,在特定n的取值条件下,T(n)能够达到上限值。正式地说,当我们谈到T(n)小于等于cn时,随着数据的变化,c作为一个常量因子不会影响到算法的运行时间。这类象在某种类型的计算机上运行算法。编译器会生成算法有关的机器码和相关常量。

很多时候我们都会遇到很多复杂的计算,所以需要非常熟悉这些计算方法。表4-1列出一些创建的复杂计算发生时的复杂度。表4-2列出了当n变化时,这些复杂度的增长速率是如何变化的。图4-1是表4-2的图形式表示。




就像一种算法的复杂度几乎不关注算法具体的运行时间,衡量算法的复杂度也没有高效或低效之说。虽然复杂度在一定程度上说明了算法效率,但一个特定的复杂度要根据具体的情况来衡量它是否高效,一般来说,在给定一定标准的情况下,能够使此算法表示出最佳时,我们就认为此算法是高效的。通常,在解决同一个问题时,如果一种算法的复杂度比其他算法的复杂度都低,并且没有过多的常数项,我们就可以认为此算法是高效的,但也会有一些棘手的问题,在这些问题中,如果不设定一个近似值就无法找到一个“有效”解决方法,这是一类特殊的问题,称为NP完全问题(NP-complete problem,见本章结尾的相关主题)。

虽然算法的复杂度是衡量算法性能的重要参考因素,但在实际应用中,我们通常还要考虑其他更多的因素。例如:当两种算法有同样的复杂度时,就得考虑对算法影响不太大的条件和因素。如果有种算法所表现出的性能可能比一个复杂度小但常量很大的算法所表现出的性能更好,其他一些值得考虑的因素包括:算法的复杂度会如何维持和发展,以及如何是一种算法在实际中更加有效的实现。一个高效的实现并不能总是影响算法的复杂度。但它可以降低常量因素的影响。从而使算法在实际应用之更加高效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值