2个nxn矩阵相处的算法可描述为:
for(i=1;i<=n;i++){ //n+1次 n次加判断1次
for(j=1;j<=n;j++){ //n(n+1)次 外n次*(内n次+内判断1次)
+ c[i][j]=0; //n*n次
for(k=0;k<n;k++){ //n*n*(n+1)次 外n*n次*(内n次+内判断1次(从0开始))
c[i][j]=c[i][j]+a[i][k]*b[k][j]; //n*n*n次
}
}
}
我们把算法所耗费的时间定义为该算法中每条语句的频度之和,则上述算法的时间消耗T(n)为:
算法的渐进时间复杂度
若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作:
称O(f(n))为算法的渐进时间复杂度(O是数量级的符号),简称时间复杂度
一般情况下,不必计算所有操作的执行次数,而只考虑算法中基本操作执行的次数,它是问题规模n的某个函数,用过T(n)表示
分析算法时间复杂度的基本办法
- 找出语句频度最大的那条语句作为基本语句
- 计算基本语句的频度得到问题规模n的某个函数f(n)
- 取其数量级用符号“O”表示
x=0;y=0;
for(k=0;k<n;k++) //n+1次
x++; //n次
for(i=0;i<n;i++){ //n+1次
for(j=0;j<n;j++) //n*(n+1)次
y++; //n*n次
}
void exam(float x[][],int m,int n){
float sum[];
for(int i=0;i<m;i++){ //m+1次
sum[i]=0.0; //m次
for(int j=0;j<n;j++){ //m*(n+1)次
sum[i] += x[i][j]; //m*n次
}
}
for(int i=0;i<m;i++){ //m+1次
cout << i << ":" << sum[i] << endl; //m次
}
}
上述嵌套最层次语句为sum[i] += x[i][j];
分析一下程序段的时间复杂度
i=0;
while(i<=n){
i*=2;
}
关键要找出来执行次数x与n的关系,并表示成n的函数
若循环执行1次:i=1x2=21;
若循环执行2次:i=2x2=22;
若循环执行3次:i=2x2x2=23;
若循环执行x次:i=2x;
设语句i*=2执行次数为x次,由循环条件i<=n
所以2x≤n => x≤log2n
即f(n)=log2n
所以该程序段的时间复杂度T(n)=O(log2n)
(2022)分析一下程序段的时间复杂度
int sum = 0;
for (int i = 1; i < n; i *= 2)
for (int j = 0; j < i; j++)
sum++;
基本语句显然为sum++;
求这道题的时间复杂度就是求sum++;
执行的次数与n的关系
若n=1,sum++;
的执行次数为0(i,j为空集)
若n=2,sum++;
的执行次数为1
若n=3,sum++;
的执行次数为3(i取{1,2},j取{0},{0,1})
若n=4,sum++;
的执行次数为3
若n=5,sum++;
的执行次数为7 (i取{1,2,4},j取{0},{0,1},{0,1,2,3})
若n=6,sum++;
的执行次数为7
若n=7,sum++;
的执行次数为7
若n=8,sum++;
的执行次数为7
若n=9,sum++;
的执行次数为15(i取{1,2,4,8},j取{0},{0,1},{0,1,2,3},{0,1,2,3,4,5,6,7})
若n=10,sum++;
的执行次数为15
sum++;
执行的次数≤ 2n-3
所以本题的时间复杂度为O(n)
算法时间复杂度计算续
顺序查找,在数组a[i]中查找值等于e的元素,返回其所在位置
for(int i=0;i<n;i++){
if(a[i] == e) return i+1; // 找到,则返回是第几个元素
}
return 0;
最好时间复杂度:1
最坏时间复杂度:n
平均时间复杂度:O(n)
渐进空间复杂度
空间复杂度: 算法所需存储空间的度量
记作:
其中 n为问题的规模
算法要占据的空间
- 算法本身要占据的空间,输入/输出,指令,常数,变量等
- 算法要使用的辅助空间
例:将一维数组a中的n个数逆序存放到原数组中
for(i=0;i<n/2;i++){
t=a[i];
a[i]=a[n-i-1];
a[n-i-1]=t;
}
t即为辅助空间,原地工作
for(i=0;i<n;i++){
b[i]=a[n-i-1];
}
for(i=0;i<n;i++){
a[i]=b[i];
}
a[n]即为辅助空间