赞
踩
评估执行程序所需的时间。可以估算出程序对处理器的使用程度。
(1)时间频率
一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
(2)时间复杂度
在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
其实就是算法(代码)的执行效率,算法代码的执行时间。我们来看下面一个简单的代码:
int sumFunc(int n) {
int num = 0; // 执行一次
for (int i = 1; i <= n; ++i) //执行n次
{
num = num + i; // 执行n次
}
return num;//执行一次
}
假设,每行代码的执行时间为t,那么这块代码的时间就是(2n+2)*t
由此得出:代码执行时间T(n)与代码的执行次数是成正比的
接下来让我们看下一个例子:
int sumFunc(int n) {
int num = 0; // 执行一次
for (int i = 1; i <= n; ++i)// 执行n次
{
for (int j = 1; j <= n; ++j)//执行n*n次
{
num = num + i * j; // 执行n*n次
}
}
}
同理,该代码执行时间为(2n*n+n+1)*t
注意:在数据结构/算法中,通常使用T(n)表示代码执行时间,n表示数据规模大小,f(n)表示代码执行次数综合,所以上面这个例子可以表示为f(n)=(2n*n+n+1)*t,其实就是一个求总和的式子,O表示代码执行时间与f(n) 成正比例。
根据上面两个例子得出结论:代码的执行时间 T(n)与每行代码的执行次数 n 成正比,人们把这个规律总结成这么一个公式:T(n) = O(f(n))
所以呢,第一个例子中的 T(n)=O(2n+1),第二个例子中的 T(n)=O(2n*n+n+1),这就是时间复杂度表示法,也叫大O时间复杂度表示法。
但是,O时间复杂度并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度,简称时间复杂度。
当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,所以可以直接忽略他们,只记录一个最大的量级就可以了,所以上述两个例子实际他们的时间复杂度应该记为:T(n)=O(n) ,T(n)=O(n*n)
(1)循环次数最多原则
我们上面说过了,当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,可以直接忽略他们,只记录一个最大的量级就可以了。因此我们在计算时间复杂度时,只需关注循环次数最多的那段代码即可。
int sumFunc(int n) {
int sum = 0; //执行1次,忽略不计
for (int i = 0; i < n; i++)
{
sum += i; // 执行n次
}
return sum; //执行1次,忽略不计
}
循环内执行次数最多,执行次数为n次,因此时间复杂度记为O(n)
(2)加法原则
int sumFunc(int n)
{
int sum = 0; //常量级,忽略
for (int i = 0; i < 99; i++)
{
sum += i; //执行100次,还是常量级,忽略
}
for (int i
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。