一.算法的定义
①算法:解决问题的一种方法或一个过程,是一个由若个运算或指令组成的有穷序列
②算法的特点:
- 有输入输出
- 确定性
- 可行性
- 有穷性
二.分析框架
先要了解时间复杂度和空间复杂度:
- 时间复杂度:执行算法需要消耗的时间长短
- 空间复杂度:执行算法需要消耗的存储空间大小
1.蛮力法
- 思想:是一种简单直接地解决问题的方法,常常直接基于问题的描述和所涉及的概念定义
- 例子:选择排序和冒泡排序,顺序查找和蛮力字符串匹配,最近对和凸包问题,穷举查找,深度和广度优先查找算法
2.减治法
- 思想:把原问题分解为小问题,再把小问题分解为更小的问题,直到得到解
- 3种主要的变化形式:①减去一个常量②减去一个常量因子③减去的规模是可变的
- 例子:插入排序,拓扑排序,约瑟夫斯问题
3.分治法
- 思想:“分而治之”,把原问题分成k个较小规模的子问题,再对这k个子问题分别求解
- 基本特征:①平衡子问题:子问题的规模大致相同②独立子问题:子问题之间相互独立
- 例子:合并排序,快速排序,二叉树遍历,大整数乘法,最近对和凸包问题
4.变治法
- 思想:将问题变换的更容易求解
- 例子:平衡查找树,推排序
5.动态规划
- 思想: 一个最优问题的任何实例的最优解,是由该实例的子实例的最优解组成的,适用于有重叠子问题和最优子结构性质的问题
- 例子:背包问题,最优二叉查找树,Floyd算法
6.贪婪法
- 思想:把整个问题分解成多个步骤,在每个步骤都选取当前步骤的最优方案,直到所有步骤结束
- 例子:Prim算法,Kruskal算法,Dijkstra算法,哈夫曼树及编码
三.渐近符号和基本效率类型
大写O符号
f(n)=O(g(n)),这里f(n)是分析出来算法的执行次数的函数,
O的定义: 当且仅当存在正的常数c和n0,使得对于所有的n>=n0,有f(n)<=cg(n)。这里cg(n)就是函数f(n)的上限。
几种函数的例子:
1.线性函数
f(n)=3n+2,当n>=2时,3n+2<=3n+n=4n。
所以f(n)=O(n),这里c = 4,n0 = 2,g(n) = n, 那么cg(n) 也就是4n 就是f(n) 的上界
2.平方函数
f(n)=2n2+3n+3,当n>=3时,3n+3<=4n,当n>=4时,4n<n2,f(n)=2n2+n2=3n^2。
f(n)=O(n^2),这里c = 3,n0 = 4, g(n) = n^2 ,那么cg(n) 也就是3n^2 就是f(n) 的上界
3.指数函数
f(n)=62n+n2,当n>=4时,n2<=2n,所以当n>=4,有f(n)<=62n+2n=7*2^n。
这里c是7,n0=4,f(n)=O(2^n)。
4.常数阶
f(n)=9,这里就直接记为O(1),c为9,n0为0就可以了,f(n)=9<=9*1。
Ω符号
定义:f(n)=Ω(g(n)),当且仅当存在正的常数c和n0,使得对于所有n>=n0,有f(n)>=cg(n)。Ω符号是给函数的下限。
例子:
对于所有的n,有f(n)=3n+2>3n,所以f(n)=Ω(n),这里c=3,n0=0。这里也可以这样f(n)=Ω(1),
Θ符号
定义:对于存在大于0的常数c1、c2和非负的整数n0,以及足够大的n,对于所有的n≥n0来说,有c1g(n)<=f (n)<=c2g(n)。
例子:
3n+2=Θ(n),当c1=3,c2=4,n>=n0=2时,3n<=3n+2<=4n。
基本的渐进效率类型
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)
四,递归与非递归算法分析
1.分析递归算法时间效率的通用方案
(1)决定用哪个(哪些)参 数作为输入规模的度量标准。
(2)找出算法的基本操作。
(3)检查一下,对于相同规模的不同输入, 基本操作的执行次数是否可能不同。如果有这种可能,则必须对最差效率、平均效率以及最优效率做单独研究。
(4)对于算法基本操作的执行次数,建立-个递推 关系以及相应的初始条件。(5)解这个递推式, 或者至少确定它的解的增长次数。
2.分析非递归算法时间效率的通用方案
(1)决定用哪个(哪些)参数表示输入规模。
(2)找出算法的基本操作(作为个规律, 它总是位于算法的最内层循环中)。
(3)检查基本操作的执行 次数是否只依赖于输入规模。如果它还依赖于一些 其他的特性,则最差效率、平均效率以及最优效率(如有必要)需要分别研究。
(4)建立一个算法基本操作执行次数的求和表达式
(5)利用求和运算的标准公式和法则来建立一个操作次数的闭合公式,或者至少确定它的增长次数