概念
时间复杂度: 一个语句的频度是指该语句在算法中被重复执行的次数。算法中所有语句的频度之和记为T(n), 它是该算法问题规模n的函数,时间复杂度主要分析T(n)的数量级。算法中基本运算(最深层循环内的语句)的频度与T(n)同数量级,因此通常采用算法中的基本运算的频度f(n)来分析算法的时间复杂度。因此,算法的时间复杂度记为
T(n) = O(f(n))
void fun(int n) {
int i = 1;
while(i <= n)
i = i*2;
}
思路:找出基础运算 i = i*2 设执行次数为t,则2的t次方<= n, t <= log以2为底的n次,因此时间复杂度为:x=2;
while(x<n/2)
x=2*x
思路:基本运算(执行频率最高的语句)为x=2x, 每执行一次x乘2,这里的x又为2,第一次是22,第二次是222, 依次类推,设执行次数为t,则有2的(t+1)次 < n/2,
int fact(int n) {
if(n = 1) return 1;
return n*fact(n-1);
}
思路:这个就是求阶乘n!的递归代码,即n(n-1)......*1, 每次递归调用时fact()的参数减1,递归出口为fact(1), 一共执行n次递归调用fact(), 故T(n) = O(n)
count = 0;
for(k = 1; k <= n; k*=2)
for(j = 1; j <= n; j++)
count++;
思路:我们知道嵌套循环的时间复杂度是两个相乘,这里不难理解,在外层的循环中,执行一次,内层就要执行一整个循环,如例题中,k为1的时候,内层循环j 用从1到n。
所以这道题先看内层,j从1到n 时间复杂度就是O(n), 外层 基础运算 k = k*2,设执行次数t,则2的t次方<=n, t <= log以2为底的n次,第一层和第二层时间复杂度相乘
int func(int n){
int i = 0, sum = 0;
while(sum < n) sum += ++i;
return i;
}
思路: 这里用到了小学知识(其实已经忘了😑)的等差数列之和,从1加到n的和,和=(首项+末项)×项数÷2, 不难看出以上就是从 0+1+2+3+4+...i = (1+i)i/2, 可知道循环次数t满足(1+t)t/2 < n, 因此时间复杂度为:
void fun(int n){
int i = 0;
while(i*i*i*i <= n)
i++;
}
思路:基本运算为i++,设执行的次数为t次,则ttt <= n, t的三次方<=n
for( i = n-1; i > 1;i--)
for(j = 1; j < i; j++)
if(A[j] > A[j+1])
A[j] 与 A[j+1] 对换
最后一行语句的频度在最坏情况下是?
思路:这是一个典型的冒泡排序,当n足够大的时候可以忽略常数,所以最坏的情况下:
以下m++执行的次数是?
int m =0, i, j
for(i = 1; i <= n; j++)
for(j = 1; j<= 2* i; j++)
m++
m++语句的执行次数:
x=0;
while(n>= (x+1)*(x+1))
x = x+1
思路:假设第k次循环终止,则第k次执行时,(x+1)的平方 > n, x的初始值为0,第k次判断时,x = k - 1, 即k的平方>n, k > 根号n, 所以: