1、算法
- 算法就是为了解决某一特定问题而规定的一系列操作,是一组有序的指令的集合。
- 算法和数据结构往往需要放在一起分析
算法的使用会使代码更加简介,程序更加快速(正确使用的情况下),例如求和1~10000,使用for循环和算法
private static void doSum(int num){int sum = 0;for (int i = 0; i <= num; i ++){sum += i;}System.out.println(sum);}private static void doSum1(int num){int sum = (1+num)*num/2;System.out.println(sum);}
1.1、算法的特性
输入:一个算法有0个或多个输入
- 输出:至少有一个输出
- 有穷性:算法中执行指令的个数应该是有限的,执行有穷的步骤后能结束
- 确定性:对于特定的合法输入,输出应该是唯一的
-
1.2、算法的设计要求
正确性:没有语法错误,对于合法是输入可以产生满足要求的输出,对于特定的输入也能够产生正确的输出
- 可读性:算法的另一个目的是为了交流,方便交流
- 健壮性:对于不合理的输入,也可以给出合理的提示信息,而不是程序崩溃
- 时间效率与存储空间:时间效率高、存储空间小
评价一个算法性能的好坏,实际上就是评价的资源占用率,计算机重要的资源就是时间和空间
使用时间复杂度来衡量程序运行占用的时间
讨论计算机程序的运行时间可以采用以下的方法:
算法1:高斯算法计算1+2+3+…+num的和
private static void doSum1(int num){int sum = (1+num)*num/2;System.out.println(sum);}
- 顺序执行,时间复杂度:T(n)=O(1),是常数阶
算法2:使用for循环计算1+2+3+…+num的和
private static void doSum2(int num){int sum = 0;for (int i = 0; i <= num; i ++){sum += i;}System.out.println(sum);}
- T(n)=O(n),线性阶
算法3:
private static void method(int num){int i = 1;int count = 0;while (i <= num){i = i *2;count++;}System.out.println(count);}
- 循环控制变量 i 的值:1,2,4,8,…,2,当执行了n次,i 的值为 2 时,循环结束,循环条件为i <= num,所以2>= num的时候循环结束
- 所以,T(n)=O(logn)
算法4:
private static void method2(int num){int count = 0;int i = 0;while(i <= num){i = i + count;count ++;}System.out.println(count);}
| count | 0 | 1 | 2 | 3 | 4 | 5 | … | x | | —- | —- | —- | —- | —- | —- | —- | —- | —- | | i | 0 | 1 | 3 | 6 | 10 | 15 | … | (0+1+2+…+x)=(1+x)*x/2=(x2+x)/2 |
- 循环控制条件false的时候,(x2+x)/2>=num的时候退出循环,当num足够大的时候T(n)=O(n2)
算法5:
private static void method3(int num){int count = 0;for (int i = 1; i <=num; i++){for (int j = 1; j <= num; j ++){count ++;}}System.out.println(count);}
| n | 1 | 2 | 3 | 4 | 5 | 6 | … | n | | —- | —- | —- | —- | —- | —- | —- | —- | —- | | count | 1 | 2 | 9 | 16 | 25 | 36 | … | n |
- 最后count++执行的次数是n次数,所以T(n)=O(n)
- 常见的时间复杂度增长率:
4、算法的空间复杂度
- 使用空间复杂度来衡量程序运行占用的空间
- 为了求解某一问题,在执行操作期间所需要的存储空间大小,一般不包含存储输入所需要的空间
- 记作:S(n)=O(f(n))
- 结论:算法的空间复杂度为上限的,所以大多数情况下我们只考虑时间复杂度
