Continued…
第二章 算法
算法的定义:算法是解决特性问题求解步骤的描述,在计算机中为指令的有限序列,并且每条指令表示一个或多个操作。
算法的特性:有穷性,确定性,可行性,输入,输出。
算法设计要求:正确性,可读性,健壮性(对于输入数据不合格的情况做合适的处理),高效率和低存储量需求。
2.1 算法效率的度量方法
事后统计方法:用测试好的程序进行多次测试,耗时耗力,不推荐。
事前分析估算方法:对于一个函数,步骤越少,肯定编译的时间就越少。每一条指令算一个时间增加区间。所以可以提前知道函数大概需要耗费的程度。如下
第一种算法:
int 1, sum = 0, n = 100; /* 执行1次*/
for (i - 1; i <= n; i++) /*执行n+1次*/
{
sum = sum + i; /*执行n次*/
}
printf("%d", sum); /*执行1次*/
第二种算法:
int sum = 0, n = 100; /*执行一次*/
sum = (1 + n) * n/2; /*执行一次*/
printf("%d",sum); /*执行一次*/
第一种算法执行了2n+3次,第二种执行了3次。但不是每次算法都是要遍历计算出来的,很多算法效率可以抽象成一个函数出来。
2.2 函数的渐进增长
一种算法2n+3次运算,另一种3n+1次运算。可见在n=2时,是判定两个算法好坏的转折点。
给出定义:输入规模n在没有限制的情况下,只要超过一个数值N,这个函数就总大于另一个函数,称函数是渐进增长的。并且当函数为高阶时,一些低阶参数以及常数项可以忽略。
2.3 算法时间复杂度
算法的时间复杂度,也就是算法的时间量度,记作:T(n) = O(f(n))。它表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法渐进时间复杂度,简称时间复杂度。用大写O()来体现算法的时间复杂度的记法,称之为大O记法。
推导大O阶:
1.用常数1取代运行时间中的所有加法常数。
2.在修改后的运行次函数中,只保留最高阶项。
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。
得到的结果就是大O阶。
2.3.1 常数阶
int sum = 0, n = 100; /*执行一次*/
sum = (1 + n) *n/2; /*执行一次*/
printf("%d",sum); /*执行一次*/
根据大O阶,第一步把项数3改成1。运行次数函数f(n)=3,时间复杂度为O(1)。
int sum = 0, n = 100;
sum = (1 + n ) *n/2; /*第1次执行*/
sum = (1 + n ) *n/2; /*第2次执行*/
sum = (1 + n ) *n/2; /*第3次执行*/
sum = (1 + n ) *n/2; /*第4次执行*/
sum = (1 + n ) *n/2<