目标
准备跟着邓俊辉的数据结构视频课学习,并配套写笔记,之后会一直更新
评价算法效率
评价算法效率两个重要概率时间复杂度和空间复杂度
1.时间复杂度:判断执行程序花费的时间。
2.空间复杂度:判断执行程序花费的存储空间。
一般主要考虑时间复杂度
时间复杂度
1.时间频度
时间频度就是程序中各个语句执行的次数,用T(n)表示,n是程序规模,n改变T(n)也就改变所以通过时间复杂度来判断n变化程序运行时间如何变化
2.时间复杂度
当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数,记作T(n)=O(f(n)),它称为算法的渐进时间复杂度,简称时间复杂度。
3.大O记号法
同样地出于保守的估计,我们首先关注T(n)的渐进上界。为此可引入所谓“大O记号” (big-O notation)。具体地,若存在正的常数c和函数f(n),使得对任何n >> 2都有 T(n) , c∙f(n) 则可认为在n足够大之后,f(n)给出了T(n)增长速度的一个渐进上界。
计算时间复杂度
1.常数O(1)
int a = 1, b = 2; //执行了一次
cout<<a+b; //执行了一次
T(n) =(1+1)=2,T(n)是一个常数,所以时间复杂度为O(1),只要T(n)是常数时间复杂度就是O(1)
2.对数O(logn)
int n; //执行一次
cin>>n; //执行一次
int i = 1; //执行一次
while(i <= n) //执行log2n+1次
{
i << 1; //执行log2n次
}
i为1只要小于等于n每次都要左移一位,设循环执行次数为t,2^t<=n解得t=log2n,底数是个常数,T(n)=(log2n+1+1+1+log2n)=(2log2n+3),大O记号法时常数忽略,所以时间复杂度为O(logn)
3.线性O(n)
int sum = 0; //执行1次
for(int i = 0; i < n; i++) //执行n+1次
{
sum +=1; //执行n次
}
T(n) = (1+n+1+n)=(2n+2),所以时间复杂度为O(n)
4.平方阶 O(n^2)
for(int i = 0; i < n; i++)
for(int j = i; j < n; j++)
{
cout<<"test"<<endl;
}
外层执行n次,外层循环第一次执行时内层循环执行n次,外层循环第二次执行时内层循环执行n-1次,一直到外层循环第n次执行时内层循环执行1次,所以T(n)=n+n-1+n-2+…+1=(n+1)n/2=n^2/2+n/2,大O记号法时阶数低的直接被忽略,常数被忽略,所以时间复杂度为O(n²)
延伸
以上只是常用的时间复杂度还有很多,如下将时间复杂度大小列出
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)