《数据结构与算法分析--C语言描述》第二章笔记
主要记录算法分析的一些理论基础,包括数学定义以及时间复杂度分析法等。
数学知识
关于时间复杂度的定义(目的在于建立一个相对的级别关系):
定义一:Θ(g(n)) = { f(n) | 如果存在正常数c1、c2和正整数n0,使得当n>=n0时,0<c1*g(n)<=f(n)<=c2*g(n)恒成立 }
定义二:Ο(g(n)) = { f(n) | 如果存在正常数c和正整数n0,使得当n>=n0时,0<=f(n)<=c*g(n)恒成立 }
定义三:Ω(g(n)) = { f(n) | 如果存在正常数c和正整数n0,使得当n>=n0时,0<=c*g(n)<=f(n)恒成立 }
1/ 若T1(n)=O(f(n)), T2(n)=O(g(n)),
则 T1(n)+T2(n)=O(max(f(n), g(n)))
T1(n)*T2(n)=O(f(n)* g(n))
2/若T(n)是以k次多项式,则T(n) = Θ(n^k)
3/对于任意常数k,log以k为底n=O(n)
常见时间复杂度推论:
Ο(1)<Ο(log2(n))<Ο(n)<Ο(n*log2(n))<Ο(n^2)<Ο(n^3)<…<Ο(2^n)<Ο(n!)
程序设计语言中对于时间的估计
简单语句
T=1;
循环
一次for循环的运行时间至少是代码块内代码运行时间总和t乘以循环次数n,T=t(循环里面的语句复杂度)*n(循环次数);
特例:
int sum = 1;
while ( sum < n )
{
sum *= 2;
}
时间复杂度为O(log n)。
嵌套的FOR循环
从里向外分析,假设两层嵌套,运行的总时间为T=t*n1(外层循环次数)*n2(内层循环次数);
特例:
for ( i = 0; i < n; i++ )
{
for( j = i; j < n; j++ )
{
}
}
时间复杂度为O(n^2)
顺序语句
将各个语句的运行时间求和,T=t1+t2+...+tn;
分支语句
运行时间不超过判断时间加上if...else...中的长者,T=t_if+t_ex;
递归函数
对于能拆解为for形式的递归,按for计算。如果不行则须列式计算。
时间复杂度的分析原则
1/例代码:
for(i = 0; i < n; i++)
a[i]++;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
a[i][j]++;
相加后其时间为n+n^2,但是 低次项通常忽略,记为O(n^2).
2/例代码
for(i = 0; i < n; i++)
{
a[i]++;
j--;
}
其时间为2*n,但是 常数项通常忽略,记为O(n)
(完)