算法:
有穷性 确定性 可行性 输入(可选) 输出
算法效率:
事后统计:计算机上的运行时间
事前分析:求出该算法一个时间界限函数
算法中基本操作重复执行的次数是问题规模n的某个函数,T(n)=O(f(n)),时间复杂度。用最深层循环内的语句中原操作的执行频度。
如果T(n) 和 f(n) 是n 的函数,当n →∞ 时,有T(n) / f(n) → c (常数c ≠ 0),记作:T(n) = O(f(n)),称O(f(n)) 为算法的渐近时间复杂度,简称时间复杂度。
时间复杂度一般有如下几种:
- O(1),O(n),O(log(n)),O(nlog(n)),O(Nk)
公理:若A(n)=amnm+am-1nm-1+……+a0是一个m次多项式,则A(n)=O(nm)
常用的多项式时间算法:
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)
常用的指数时间算法:
O(2n)<O(n!)<O(nn)
如果能把一个指数时间复杂度的算法,简化为多项式时间复杂度,那么就是大牛
了。
下面看一个简单算法,判断一个值是否为质数:
#include<stdio.h>
#include<math.h>
int main()
{
//判断是否是质数
int i=2,n;
printf("请输入一个正整数:\n");
scanf("%d",&n);
while((n%i)!=0 && i*1.0 < sqrt(n))
i++;
if(i*1.0>sqrt(n))
printf("%d是一个质数",n);
else
printf("%d不是一个质数",n);
}
由上述代码可以看出,嵌套的最深层语句是i++,循环次数主要是由sqrt(n)来决定,所以该代码时间复杂度是:O(n1/2)
再来看一个常用算法,冒泡排序:
#include<stdio.h>
#define NUM 5
void sort(int a[], int n)
{
int i,j;
for(i=0;i<n-1;i++) //排序n-1趟
for(j=0;j<n-i-1;j++){//每一趟做的比较
if(a[j]>a[j+1]){ //相反顺序改一下比较符号
a[j]=a[j+1]+a[j];
a[j+1]=a[j]-a[j+1];
a[j]=a[j]-a[j+1];
}
}
}
int main()
{
int a[NUM]={4,8,2,3,7};
sort(a,NUM);
printf("排序后的数据为:");
for(int i=0;i<NUM;i++)
printf("%d ",a[i]);
}
最好情况复杂度:0
最坏情况下复杂度:1+2+....+n-1=n(n-1)/2 也就是O(n2)