算法
算法:
是指令的集合,是为解决特定的问题而规定的一系列操作,有明确定义的可计算过程,以一个数据集合作为输入,并产生一个数据集合作为输出。
特征:
1、输入项(Input):一个算法应以待解决的问题的信息作为输入
2、输出项(Output):输入对应指令处理后得到的消息
3、有穷性(Finiteness):算法执行的指令个数是有限的,每个指令又是在有限的时间内完成的,因此整个算法也是在有限时间内可以结束的。
4、确切性(Definitenss):算法对于特定的合法输入,其对应的输出是唯一的,即当算法从一个特定输入开始多次执行同一指令集结果总是相同的。
5、可行性(Effectiveness):算法是可行的,即算法的每一条指令都是可以实现的
复杂度:评价算法优劣的依据 (算法的优劣取决于算法的复杂度)
算法复杂度体现在运行该算法时计算机需要多少资源,而对于计算机而言时间和空间资源尤为重要,所以复杂度分为时间复杂度和空间复杂度
时间复杂度:指执行算法需要的计算工作量
一个算法中花费的时间与算法中语句执行次数(时间频度)成正比。
时间频度:一个算法中语句执行次数,表示为T(n),n代表问题规模
例如:某几个算法的时间频度:
T(n)=10000n2+10n+6
T(n)=10n2+10n+6
T(n)=n2
T(n)=n2
T(n)=n2
T(n)=n2
综上所述,我们可以只考虑算法实现的规模,而不是具体次数,所以可以用时间复杂度表示,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示。
时间复杂度:T(n)=O(n^2)
时间复杂度不是一个真正意义上的时间,不是一个算法真正执行的次数,而是一个算法执行的规模。(或者可以说时间复杂度就是时间频度去掉低阶项和首项常数,然后用O表示)
最坏时间复杂度:
T(n)=O(n),表示对于任何输入实例,该算法的运行时间不可能大于O(n)
最坏情况下的时间复杂度(最大规模时间)
平均时间复杂度
时间复杂度如何计算:
1、找出算法中的基本语句:
算法中执行次数最多的那条语句就是基本语句,(比如内层的循环体)
2、计算基本语句的执行次数的数量级
执行需要计算基本语句执行次数的数量级就意味着只要保证基本语句执行次数的函数中的最高次幂正确即可,可以忽略所有低次幂的系数,简化算法分析。
3、用大O记号表示算法的时间性能
将基本语句执行次数的数量级放入大O记号中
时间复杂度举例:
1、一个简单语句的时间复杂度为O(1)
int count=0;
T(n)=1(时间频度)
T(n)=O(1)(时间复杂度)
2、100个简单语句的时间复杂度为O(1)
int count=0;(基本语句)
count=0;
count=0;
count=0;
count=0;
…
T(n)=1(时间频度)
T(n)=O(1)(时间复杂度)
3、一个循环的时间复杂度是
for n=8,count=0;
for(int i=1;i<=n;i++){
count++;(基本语句)
}
T(n)=n(时间频度) (n决定语句的执行次数)
T(n)=O(n)(时间复杂度)
4、时间复杂度为O(log2𝑛循环语句
int n=8,count=0;
for(int i=1;i<=n;i*=2){
count++;
}
i*=2:1\2\4\8\16\32…
2^30:2^10^3:10亿
T(n)=n(时间频度)
T(n)=O(log2𝑛)时间复杂度
5、时间复杂度为O(n^2)的二重循环
int n=8,count=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
count++;
}
}
T(n)=100n*10n(时间频度)
T(n)=O(n*n)(时间复杂度)
6、时间复杂度为O(nlog2𝑛)的二重循环
int n=8,count=0;
for(int i=1;i<=n;i*=2){
for(int j=1;j<=n;j++){
count++;
}
}
T(n)=n(时间频度)
T(n)=O(nlog2𝑛)(时间复杂度)
7、时间复杂度为O(n^2)的二重循环
int n=8,count=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
count++;
}
}
T(n)=(1+n)*n/2(时间频度)
T(n)=O(n^2)(时间复杂度)
时间复杂度是衡量算法优劣的指标
复杂度越高,执行效率越低
常见的时间复杂度按数量级递增排序依次为:
常见阶O(1)<对数阶O(log2𝑛)<线性阶O(n)<平方阶O(n^2)
空间复杂度:指执行算法需要的内存空间
1、程序本身占用空间
2、输入数据占用空间
3、辅助变量占用空间
S(n)=O(g(n))