1.算法的效率
算法的效率从一般从两个方面分析:时间效率和空间效率。时间效率又称时间复杂度,空间效率又称空间复杂度。
时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要占用额外的空间。
2.时间复杂度
2.1时间复杂度的定义
算法的时间复杂度是一个函数,它定量的描述算法的运行时间。一个算法的执行所消耗的时间,从理论上来说,是不可能算出来的,而且由于每个人的机器不同,算法的执行所消耗的时间也会有所不同。由于算法执行所消耗的时间与其中的语句执行的次数成正比。所以:
算法中的基本操作执行的次数,为算法的时间复杂度。
2.2大O的渐进表示法
用来推断基本操作执行的大概次数
- 用常数1取代运行时间中的所有加法常数。
- 在修改后的运行次数函数中,只保留最高价项。
- 如果最高阶项存在且不是1,则去除与这个项目相乘的常熟,得到的结果就是大O阶。
例如:
public void function1(){
int m = 10;
int count = 1;
while(m > 0){
count++;
m--;
}
}
while循环执行十次,两个基本语句,共执行了10+2次。由于用常数1代替所有的加法常数,故function1的时间复杂度为O(1);
public void function2(int n){
int count = 0;
int m = 10;
while(m > 0){
count++;
m--;
}
for(int i = 0; i < n ;i++){
for(int j = 0; j < n;j++){
count++;
}
}
两个嵌套for循环执行的次数为N^2,while循环执行的次数为10次,外加两个基本语句,共执行了 N ^2 + 10 + 2 次。只保留最高阶,最高阶系数化为1,故function2的时间复杂度为O(N ^2)。
二分法的时间复杂度为log2(N)
int fibonacci(int N) {
return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
}
递归的时间复杂度:递归的次数 * 每次递归执行操作的次数
斐波那契数列的时间复杂度为O(N^2),由于是进行函数的递归,故利用画图思考,可知为2的等比数列。
3.空间复杂度
3.1 空间复杂度的定义
空间复杂度是对一个算法在运行过程中临时占用储存空间大小的量度。
空间复杂度不是程序占用了多少byte的空间,这没有什么太大的意义,所以空间复杂度是指的是变量的个数,使用大O渐进表示法。
public void function3(){
int m = 10;
int count = 0;
while(m > 0){
count++;
m--;
}
}
function3定义了两个变量,根据大O渐进法可知为function3的空间复杂度为O(3)。
public void function4(int n){
int[] array = new int[n];
for(int i = 0; i < n;i++){
array[i] = i;
}
}
function4中定义了一个占用包含N个int类型的数组,故function4的空间复杂度为O(N)。
long factorial(int N) {
return N < 2 ? N : factorial(N-1)*N;
}
factorial递归调用N次,开辟了N个栈帧,每个栈帧使用了常数个空间,空间复杂度为O(N)。
3.小结
3.1时间复杂度
时间复杂度有时也存在最好、平均、最坏情况。
最好情况:任意输入规模的最小运行次数(下界)
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
3.2 private关键字
- 是一个权限修饰符;
- 用于修饰成员(成员变量和成员方法);
- 被私有化的成员只能在本类中有效;
常用之一:
将成员变量私有化,对外提供对应的set,get方法对其进行访问。提高对数据访问的安全性;
3.3 static修饰符
static int age; 是静态字段或静态变量
public static void function(){…}; 是静态方法
static{…} 是静态的初始化块
被static关键字修饰的方法或者变量不需要依赖于对象来进行访问
在类第一次加载的时候,会进行静态字段的初始化