笔记:算法的基本知识点

《大话数据结构》第2章 算法 —— 笔记

下载链接,提取码:wr3p

算法的定义
  • 算法:描述解决问题的方法。是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
算法的特性

算法的五个基本特性:

  • 输入:零个或多个
  • 输出:至少一个或多个。形式可以是打印输出,或返回一个或多个值
  • 有穷性:在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
  • 确定性:算法的每一步骤都具有确定的含义,不会出现二义性。一定条件下只有一条执行路径,相同的输入只能有唯一的输出结果。
  • 可行性:每一步必须是可行的,每一步都能通过执行有限次数完成。
算法设计的要求
  1. 正确性。大体分为四个层次(按要求从低到高,一般把层次3作为一个算法是否正确的标准):
    1. 算法程序没有语法错误;
    2. 算法程序对于合法的输入数据能够产生满足要求的输出结果;
    3. 算法程序对于非法的输入数据能够得出满足规格说明的结果;
    4. 算法成对对于精心选择的,甚至刁难的测试数据都有满足要求的输出结果。
  2. 可读性。便于阅读、理解和交流。
  3. 健壮性。当输入数据不合法时,也能做出相关的处理,而不是产生异常或莫名其妙的结果。
  4. 时间效率高和存储量低。花最短的时间、最少的钱,办最大的事。
算法效率的度量方法

这里效率大多指算法的执行时间。如何度量算法的执行时间呢?

(1)事后统计方法——麻烦,成本高,一般不予考虑

这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。

(2)事前分析估算方法

在计算机程序编制前,依据统计方法对算法进行评估。

一个程序在计算机上运行时所消耗的时间取决于下列因素:

  1. 算法采用策略、方法 —— ✔这是算法好坏的根本
  2. 编译产生的代码质量 —— 要由软件来支持
  3. 问题的输入规模
  4. 机器执行指令的速度 —— 要看硬件性能。

测定运行时间可靠的方法就是:计算对运行时间有消耗的基本操作的执行次数。运行时间与这个计数成正比。(只关心实现的算法,不计哪些循环索引的递增和循环终止条件、变量声明、打印结果等操作。)

在分析算法的运行时间时,把基本操作的数量表示成输入规模 n n n的函数。

在这里插入图片描述

函数的渐进增长

给出这样的定义:输入规模 n n n在没有限制的情况下,只要超过一个数值 N N N,这个函数就总是大于另一个函数,我们称函数是渐进增长的。

函数的渐进增长:给定两个函数 f ( n ) f(n) f(n) g ( n ) g(n) g(n),如果存在一个整数 N N N,使得对于所有的 n > N n>N n>N f ( n ) f(n) f(n)总是比 g ( n ) g(n) g(n)大,那么,我们说 f ( n ) f(n) f(n)的增长渐进快于 g ( n ) g(n) g(n)

判断一个算法好不好,我们只通过少量的数据是不能做出准确判断的,如果我们可以对比算法的关键执行次数函数的渐近增长性,基本就可以分析出:某个算法,随着 n n n的变大,它会越来越优于另一算法,或者越来越差于另一算法。

判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数。

算法时间复杂度

在进行算法分析时,语句总的执行次数 T ( n ) T(n) T(n)是关于问题规模 n n n的函数,进而分析 T ( n ) T(n) T(n) n n n的变化情况并确定 T ( n ) T(n) T(n)的数量级。

算法的时间复杂度,也就是算法的时间量度,记作: T ( n ) = O ( f ( n ) ) T(n) = O(f(n)) T(n)=O(f(n)) —— 大O记法
它表示随问题规模 n n n的增大,算法执行时间的增长率和 f ( n ) f(n) f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中 f ( n ) f(n) f(n)是问题规模 n n n的某个函数。

推导大O阶:

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

得到的结果就是大O阶。

分析算法的复杂度,关键是要分析循环结构的运行情况。

循环的时间复杂度 = 循环体的复杂度 × 该循环运行的次数

理解大O推导不算难,难的是对数列的一些相关运算,这更多的是考察你的数学知识和能力。

常见的时间复杂度

非官方名称: O ( 1 ) O(1) O(1) 常数阶, O ( n ) O(n) O(n) 线性阶, O ( n 2 ) O(n^2) O(n2) 平方阶, O ( log ⁡ n ) O(\log n) O(logn) 对数阶, O ( 2 n ) O(2^n) O(2n) 指数阶, O ( n ! ) O(n!) O(n!) 阶乘阶

常用的时间复杂度所耗费的时间从小到大排序:

O ( 1 ) < O ( log ⁡ n ) < O ( n ) < O ( n log ⁡ n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1) < O(\log n) < O(n) < O(n\log n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

O ( n 3 ) , O ( 2 n ) , O ( n ! ) , O ( n n ) O(n^3), O(2^n), O(n!), O(n^n) O(n3),O(2n),O(n!),O(nn) ,除非是很小的 n n n值,否则哪怕 n n n只是100,都会是噩梦般的运行时间。

最坏情况与平均情况

对算法的分析,一种方法是计算所有情况的平均值,这种时间复杂度的计算方法称为平均时间复杂度。另一种方法是计算最坏情况下的时间复杂度,这种方法称为最坏时间复杂度。

一般在没有特殊说明的情况下,都是指最坏时间复杂度。

算法空间复杂度

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

一般情况下,一个程序在机器上执行时,除了需要存储程序本身的指令、常数、变量和输入数据外,还需要存储对数据操作的存储单元。

若输入数据所占空间只取决于问题本身,和算法无关,这样只需要分析该算法在实现时所需的辅助单元即可。

若算法执行时所需要的辅助空间相对于输入数据量而言是个常数,则称此算法为原地工作,空间复杂度为 O ( 1 ) O(1) O(1)

通常,我们都使用“时间复杂度”来指运行时间的需求,使用“空间复杂度”指空间需求。当不用限定词地使用“复杂度”时,通常都是指时间复杂度。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值