数据结构心得1:时间复杂度
最近要考数据结构了,整理一波心得当作复习吧。时间复杂度这个概念对于一些同学来说,还是有一些难度的,那我就讲一讲的认识的时间复杂度吧。
本文主要分为以下三个部分:
1.时间复杂度
2.时间复杂度计算举例
3.几种排序算法的时间复杂度
1.时间复杂度
什么是时间复杂度?比如说,现在有一个算法,你想评价它运算需要耗费的时间,这个时候上机跑一遍肯定不太实际,而且不同的机器跑的速度也会不一样,所以为了去评价算法运算的时间,就引出了时间复杂度的概念。
1)时间频度
算法需要花费的时间,和它语句执行的次数是成正比例的,因此把一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
2)时间复杂度
在上面提到的时间频度T(n)中,n是指算法的规模,n不断的变化,T(n)就会不断的变化,为了衡量T(n)随n的变化规律,引入了时间复杂度的概念。
什么是时间复杂度,从数学的角度给出定义:算法中某个函数有n次基本操作重复执行,用T(n)表示,现在有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度(我们都学过高数,我高数72都能看懂,相信大家都能理解这段话)。
简要的说,就是找一个与T(n)同一数量级的函数f(n),然后写成O(f(n))就ok了。
3)时间复杂度计算
简单的说,时间复杂度O是总运算次数T(n)表达式中受n的变化影响最大的那一项。举个例子: T(n) = n^3+n^2+n+23,那么它的时间复杂度就是O(n^3)。
2.时间复杂度计算举例
1)O(1)
Eg1:
c = b;//执行1次
b = a;//执行1次
a = c;//执行1次
所以T(n)= 3 = O(1)。
注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
Eg2:
x=91;
y=100;
while(y>0) {
if(x>100)
{
x=x-10;
y--;
}
else x++;
}
T(n) = O(1)。
循环次数此时已定,时间复杂度是O(1)。
注意:一个函数调用或是一组语句都认为是O(1)的复杂度(如果没有调用不包含循环,递归或其他非常量复杂度的函数)。如果循环的次数是一个常量,则也认为是 O(1)。
2)O(n^c)
Eg1:
for (int i = 1; i <= n; i += c) {//执行n次
for (int j = 1; j <= n; j += c) {//执行n^2次
a += 1;//执行n^2次
}
}
T(n) = n + n^2 +n^2 = O(n^2)
Eg2:
a = 0;//执行1次
b = 1;//执行1次
for (i = 1;i <= n;i ++) {//执行n次
s=a+b;//执行n-1次
b = a;//执行n-1次
a = s;//执行n-1次
}
T(n) = 2 + n + 3 * (n - 1) = O(n)
嵌套循环的时间复杂度等于行最内层语句执行的次数。
3)O(logc n)
Eg1:
for (int i = 1; i <= n; i *= c) {//设频度为f(n)
a = a + 1;
}
设for语句中,i *= c的频度为f(n),那么c^f(n) <= n,也就是说,最多执行n次,所以f(n) = logc n,所以O(logc n)
对于for中有除法的,也是一样的存在。
Eg2:
for (int i = n; i > 0; i /= c) {
a = a + 1;
}
同样是O(logc n)。
注意:如果在一个大小为n循环中,循环变量按照一个常量C的进行倍数的递增或递减,这个循环的复杂度就为O(logc n)。
最后附上一个大佬分享的经验规律:其中c是一个常量,如果一个算法的复杂度为c 、 log2n 、n 、 n*log2n ,那么这个算法时间效率比较高 ,如果是2n ,3n ,n!,那么稍微大一些的n就会令这个算法不能动了,居于中间的几个则差强人意。https://www.cnblogs.com/suiying/p/4748490.html
3.几种排序算法的时间复杂度