文章目录
前言
在谈论算法的时间复杂度之前,有必要介绍一下算法的特性,因为只有度量一个“合法”的算法运行效率才是有意义的。算法的特性主要包含四个方面:输入、输出、有穷性、确定性和可行性。
- 输入输出:算法具有零个或多个输入,至少有一个输出
- 有穷性:必须在执行有限的步骤之后,能自动介绍而不会出现无限循环
- 确定性:算法执行的每一个步骤必须是确定的,无二义性的
- 可行性:算法的可以在机器上运行,并得到正确的结果
在简单谈论了算法的特性之后,该做什么呢?算法的四个特性规定了一个基本的算法该有的”样子“,而人类总是”贪婪“的,我们追求的是优质的算法,那什么样的算法是优质的呢?
没错,高效且健壮是算法设计的目标!
所谓高效指的是算法能在尽量短的时间内运行得到正确的结果;所谓健壮指的是算法面对不同的输入数据或者不合法的数据,具有较强的自我分辨能力,比如:要求视觉识别算法能够在较为极端的光照环境下也能正确运行;输入非法的数据能够识别,而不是产生莫名其妙的错误。
算法的运行效率度量
(1)What(什么是算法的运行效率)
本质就是算法从开始运行到运行结束运行时间,运行时间越短,效率越高
(2)How(如何度量算法的运行效率)
事后统计方法:
简单来说在同一环境中跑不同的算法,统计不同算法的运行时间来比较算法的运行效率;这种度量方法要求必须实现编写好算法,如果算法复杂,则需要花费大量的时间和经历来运行测试,且依赖于计算机软硬件等环境因素
事前分析估算方法:
在计算机程序编写之前,依据统计方法对算法进行估算
(3)时间复杂度
A. What(什么是时间复杂度)
本质是一个函数,它定性描述了该算法的运行时间。它用于衡量算法运行时间随输入规模增长的速度
T(n) = O(f(n)),其中n表示问题的规模,函数f(n)是关于问题规模的函数,在实际计算时,通常是统计所有语句执行的次数得到该函数
下面将介绍时间复杂度的计算步骤:
- step01:计算问题规模和算法执行次数的函数表达式,即y = f(n),n表示问题规模,y表示算法语句执行的总次
- step02:对f(n)函数进行大O阶推导,常见的大O阶有常数阶、线性阶、对数阶、平方阶、立方阶等
B. 示例分析:求解算法的时间复杂度
long calCubeSum(int n){
long sum; // 标号1
while(sum<n){ // 标号2
sum = sum*2; // 标号3
}
return sum; // 标号4
}
先求解f(n):
标号1:执行1次
标号2:执行log2(n)次
标号3:执行log2(n)次
标号4:执行1次
f(n) = 1 + log2(n) + log2(n) + 1 = 2log2(n) + 2;
在求解T(n): 只保留最高阶项
T(n) = O(f(n)) = O(logn)
C.常见的时间复杂度及排序
常数阶、对数阶、nlogn阶、平方阶、立方阶、指数阶、n!阶等;其从小到大排序如下:
O(1) < O(logn) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)