数据结构和算法【第1章 绪论】第三部分

目录

 

第1章 绪论

第三部分

1.算法效率的度量方法

2.函数的渐近增长

3.算法的时间复杂度

4.推导大O阶方法

5.函数调用的时间复杂度分析

6.算法的空间复杂度


第1章 绪论

第三部分

1.算法效率的度量方法

  1. 时间效率高就是算法的执行时间少。那么如何度量一个算法的执行时间呢?
  2. 事后统计方法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。有以下缺陷。
    • 必须依据算法事先编制好的测试程序,通常需要花费大量的时间和精力。
    • 不同的测试环境差别很大。
  3. 事前分析估算法:在计算机程序编写之前,依据统计方法对算法进行估算。
  4. 程序在计算机上面运行时所消耗的时间取决于下列因素
    • 算法采用的策略、方案。 人为
    • 编译产生的代码质量。
    • 问题的输入规模。 人为
    • 机器执行指令的速度。

例如:

循环求累加的值循环算法

int num = 100;
int sum = 0;
for (int i = 1; i <= num; i++) {
    sum += i;
}
System.out.println("sum" + sum);

执行了 1+(n+1)+n=2n+2次,但是高斯算法

int num = 100;
int sum = 0;
sum = (1 + num) * num / 2;
System.out.println("sum" + sum);

执行了1+1=2次,如果我们把循环看做一个整体,忽略头尾判断的开销,那么这两个算法其实就是n和1的差距。

ps:我们研究算法的复杂度,侧重的是研究算法随着输入规模的扩大增长量的一个抽象,而不是精确的定位到需要执行多少次。

  1. 不关系编写程序的语言,不关心在什么计算器上面运行,只关心算法本身。
  2. 不计循环索引的递增和循环终止条件、变量声明、打印结果等操作。最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或者一系列的步骤。
  3. 我们在分析一个算法的运行时间时,重要的是把基本操作的数量和输入模式关联起来。

2.函数的渐近增长

  1. 函数的渐进增长:
    1. 给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>Nf(n)总是比g(n)大,那么我们说f(n)的增长渐近快于g(n)。可以忽略加法常数。例如f(n)=n^2,g(n)=2n,当超过N=2时,f(n)总是比g(n)大,那么我们说f(n)的增长渐近快于g(n)
       f(n)=n^2g(n)=2n
      n=112
      n=244
      n=396
      n=4168
      n=52510
      n=63612

       

    2. 判断一个算法的效率的时候,函数中的常数和其他次要项常常可以忽略,而更应该关注主项*(最高项)的阶数
    3. 判断一个算法少量数据是不能做出准确判断的。

3.算法的时间复杂度

  1. 算法时间复杂度:在进行算法分析的时候,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随着n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度。记作:T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度。其中f(n)是问题规模n的某个函数。
  2. 这样用O()来体现算法时间复杂度的记法,我们称之为大O记法。、
  3. 一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。
  4. 显然,由此算法时间复杂度的定义可以知道,我们的三个求和算法的时间复杂度如下
    • f(n)=2 ==>O(1)
    • f(n)=2n+2 ==>O(n)
    • f(n)=n^2 ==>O(n^2)

4.推导大O阶方法

  1. 用常数1取代运行时间中的所有加法常数。例如2n^2+2n+3抽象成 2n^2+2n
  2. 在修改后的运行次数函数中,只保留最高阶项。例如2n^2+2n+3抽象成2n^2
  3. 如果最高阶项存在并且不是1,那么去除与这个项相乘的常数。例如2n^2+2n+3抽象成n^2
  4. 得到的最后结果就是大O阶。
  5. 大O阶一般有以下几种
    • 常数阶。常数次的大O记作O(1),没有O(10).....什么其他的东西。
    • 线性阶。一般含有非嵌套循环涉及线性阶,线性阶就是随着问题规模n的扩大,对应计算次数呈现直线增长。例如2n+1,时间复杂度就是O(n)
    • 平方阶。一般含有嵌套循环的涉及平方阶。平方阶就是随着问题规模n的扩大,对应计算次数呈现平方增长。例如1/2*n^2+n/2的时间复杂度是O(n^2)
    • nlogn阶。 例如2n+3nlog(2)n+14,时间复杂度是O(nlogn)。

    • 立方阶。 例如n^3+2n^2+6,时间复杂度是O(n^3)。

    • 指数阶。 例如2^n,时间复杂度是O(2^n)。

    • 对数阶。

比如:

int i = 1, n = 100;

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

由于每次i*2之后,就距离n更进一步。假设有x个2相乘后大于或者等于n, 那么就会退出循环。2^x=n;所以x=log(2)n,所以这个循环的时间复杂度是 O(logn)。

5.函数调用的时间复杂度分析

  1. 常用时间复杂度所耗费的时间从小到大依次是:O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
  2. 最坏情况与平均情况。
    1. 最坏运行时间是一种保证。在应用中,这是一种最重要的需求,通常除非特别指定,我们提到的运行时间都是最坏情况的运行时间。
    2. 平均运行时间是期望的运行时间。

6.算法的空间复杂度

  1. 例如判断某年是否为闰年。可以现成计算,也可以事先初始化一个2050年的一个数组,利用特殊标示来表示年份是否为闰年。这种就是利用空间来换取时间。
  2. 算法的空间复杂度通过计算算法所需的存储空间实现,算法的空间复杂度的计算公式记作:S(n)=O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。
  3. 通常,我们用“时间复杂度”来指运行时间的需求,用“空间复杂度”来指运行空间的需求。
  4. 当直接要求求“复杂度”的时候,通常指的是求“时间复杂度”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值