1. 算法、语言、程序的关系
① 算法:解题步骤
② 语言:描述算法的一种工具,工具包括自然语言、程序设计语言、框图、伪代码等。
③ 程序:使用某种语言,在计算机中实现算法。
2. 设计实现算法的步骤
① 确定结构关系:找出与求解有关的数据元素之间的关系。
② 确定运算集合:确定在某一数据对象上所施加的运算。
③ 存储结构:数据元素的存储表示。
④ 语言选择:用于描述算法
⑤ 设计算法
算法的时间性能分析
算法耗费的时间
一个算法执行时间是指算法所有语句执行时间的总和。
但执行时间与计算机软硬件条件相关
语句频度
语句频度:该语句在一个算法中重复执行的次数。
算法的时间耗费=所有语句频度之和
例如:如下两个N×N矩阵相乘的算法,求算法的时间耗费。
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ c[i,j]=0;
for (k=0; k<n; k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
语句频度
n+1
n(n+1)
n2
n2(n+1)
n3
f(n) = 2n3+3n2+2n+1
算法的时间复杂度(渐近时间复杂度)
(1)算法的时间复杂度T(n)
算法的时间复杂度T(n):定义为该算法所耗费执行时间的数量级,就是渐近时间复杂度。
T(n) = O(f(n))
表示:随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同。
例如:如下两个N×N矩阵相乘的算法,求算法的时间复杂度。
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ c[i,j]=0;
for (k=0; k<n; k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
语句频度
n+1
n(n+1)
n2
n2(n+1)
n3
f(n) = 2n3+3n2+2n+1
T(n) = O(n3)
(2)原操作
是指从算法中选取一种对所研究问题时基本运算的操作。
原操作即基本操作,如赋值操作。
例如:如下两个N×N矩阵相乘的算法,求算法的时间复杂度。
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ c[i,j]=0;
for (k=0; k<n; k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
语句频度
n2
n3
f(n) = n2+n3
T(n) = O(n3)
例如:如下两个N×N矩阵相乘的算法,求算法的时间复杂度。
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{ c[i,j]=0;
for (k=0; k<n; k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
最大的语句频度
n3
f(n) = n3
T(n) = O(n3)
例如:常数阶
temp=i;
i=j;
j=temp;
f(n)=3
T(n)=O(f(n))=O(3n0)=O(1)
例如:线性阶
for (i=0; i<n; i++)
x=x+1;
f(n)=n
T(n)=O(f(n))=O(n)
例如:平方阶
x=0; y=0;
for (i=0; i<n; i++)
x++;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
y++;
f(n)=n2 T(n)=O(f(n))=O(n2)
例如:计算下列算法原操作x=x+1的语句频度以及算法的时间复杂度
x=1;
for (i=1; i<=n; i++)
for (j=1; j<i; j++)
x=x+1;
f(n)=1+2+…+n=n(n+1)/2
T(n)=O(n2/2+n/2)= O(n2)
常用算法时间复杂度
O(1)常数型
O(n)线性型
O(n2)平方型
O(n3)立方型
O(2n)指数型
O(log2n)对数型
O(nlog2n)二维型
6.最坏时间复杂度和平均时间复杂度
例:下列算法用于在a[0…n-1]查找给定值k,分析算法的时间复杂度。
(1) i=n-1;
(2) while(i>=0&&(a[i])!=k)
(3) i–;
(4) return i;
最坏、最好情况下语句(3)的语句频度?
最坏语句频度=n
算法的时间复杂度依赖于问题的规模n和输入实例的初始状态时,要考虑最坏时间复杂度。
时间复杂度均是指最坏时间复杂度。
T(n) = O(n)
等概率情况下,语句(3)的平均频度
平均时间复杂度
= 1/𝑛 (0+1+…+(𝑛−1))=(𝑛−1)/2
或者
= 1/(𝑛+1) (0+1+…+𝑛)=𝑛/2
期望下,查找次数为问题规模一半。