算法
算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
注:算法定义中,提到了指令,指令能被人或计算装置执行。它可以是计算机指令,也可以是我们平时的语言文字。
程序 = 数据结构 + 算法
算法的五个特性
- 有穷性:一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都可在有穷时间内完成。
- 确定性:算法中每一条指定必须有确切的含义,读者理解时不会产生二义性。并且在任何条件下,算法只有惟一的一条执行路径,即对于相同的输入只能得出相同的输出。
- 可行性:一个算法是能行的。即算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的。
- 输入:一个算法有零个或多个的输入,这些输入取自于某个特定的对象的集合。
- 输出:一个算法有一个或多个的输出,这些输出是同输入有着某些特定关系的量。
注意:算法必须是有穷的,而程序可以是无穷的。
算法设计的要求
- 正确性:算法能够满足具体问题的需求。
- 可读性:算法主要是为了人的阅读与交流,其次才是机器执行。可读性好有助于人对算法的理解。
- 健壮性:当输入数据非法时,算法也能适当地做出反应或进行处理,而不会产生莫名其妙的输出结果。
- 时间效率高与存储量低:效率指的是算法执行的时间。存储量需求指算法执行过程中所需要的最大存储空间。
算法效率的度量方法
1)事后统计法
这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。
2)事前统计法
在计算机程序编制前,依据统计方法对算法进行估算。
一个用高级程序语言编写的程序在计算机上运行时所消耗的时间取决干下列因素:
最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。
判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数。
时间复杂度
时间复杂度定义
注:除非特别指定,通常我们提到的运行时间都是最坏情况的运行时间。
推导大O阶
O(1):常数阶
O(n):线性阶
O(n^2):平方阶
对数阶
常见的时间复杂度
常<对<幂<指<阶
求和定理:假设T1(n)和T2(n)是程序段P1、P2的执行时间,并且T1(n)= O(f(n)), T2(n)=O(g(n)),那么
总执行时间复杂度是T1(n)+T2(n)= O(MAX(f(n),g(n)))。(多个并列循环)。
求积定理:假设T1(n)和T2(n)是程序段P1、P2的执行时间,并且T1(n)= O(f(n)), T2(n)=O(g(n)),那么
总执行时间复杂度是T1(n)*T2(n)= O(f(n)*g(n))。(多层嵌套循环·)
1)顺序执行的代码只会影响常数项,可以忽略
2)只需挑选循环中的一个基本操作分析它的执行次数与n的关系即可。
3)如果有多层嵌套循环,只需关注最深层循环循环了几次。
最坏时间复杂度:最坏情况下算法的时间复杂度
最好时间复杂度:最好情况下算法的时间复杂度
平均时间复杂度:所有输入示例等概率出现的情况下,算法的期望运行时间
时间复杂度是指最坏时间复杂度,只关注最高此项,只有常数项记作1。
空间复杂度
算法存储包含:输入数据所占的空间、程序本身所占的空间和临时变量所占的空间。
算法空间复杂度 S(n) = O(f(n))
算法原地工作指算法所需的辅助空间为常量,S(n)= O(1)。
空间复杂度,只需关注存储空间大小与问题规模相关的变量。