目录
算法需求:耗费时间少,耗费内存少。那么我们应该如何去衡量不同算法之间的优劣呢?
主要还是从算法所占用的「时间」和「空间」两个维度去考量。
时间维度:是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述。
空间维度:是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述。
时间复杂度分析
分析的方法有两种:事后分析估算方法,事前分析估算方法。
事后分析估算方法:通过自写测试程序来记录时间,而且根据硬件环境有可能有不同结果。所以不建议说使用此办法。
事前分析估算方法:一个高级语言编写的程序在计算机上消耗的时间取决于
- 算法采取的策略和方案
- 编译产生的代码质量
- 问题输入的规模
- 机器执行指令的速度
大o的渐进表示法
大O表示法:算法的时间复杂度通常用大o符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。
大O符号:是用来描述函数渐进行为的符号
大O阶方法:
- 选用阶数最高的一项,忽略这一项的系数。
- 常数使用1代替。
常见代码的时间复杂度分析
1.冒泡排序
public class text {
public static void bubbleSort(int []arr){
for(int i=0;i<arr.length-1;i++){
boolean flag=true;
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]<arr[j+1]){
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
flag=false;
}
}
if(flag){
break;
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 2, 5, 6, 7, 8};
bubbleSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
冒泡排序,时间复杂度:最差O(N²),最好O(N)
2.折半查找
public static void search(int []arr,int target) {
int left = 0, right = arr.length - 1;
while (left < right) {
int mid = (left + right) / 2;
if (arr[mid] < target) {
left = mid + 1;
} else if (arr[mid] > target) {
right = mid - 1;
} else {
System.out.println("找到了,下标" + mid);
break;
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
search(arr, 6);
}
二分查找:时间复杂度:log₂N,最好情况O(1) 每执行一次查找,查找范围减半,直到最后找到或找不到,也就是说2^x=N,解出x=log₂N
3.递归---斐波那契数列
递归的时间复杂度=递归执行次数*一次递归的执行次数
public static int Fun(int n){
if(n<=2)
return 1;
else
return Fun(n-1)+Fun(n-2);
}
public static void main(String[] args) {
int s=6;
System.out.println(Fun(s));
}
使用递归求斐波那契数列:时间复杂度O(2^N)
空间复杂度
空间复杂度:计算定义的变量个数。采用大O表示法
public class text {
public static void bubbleSort(int []arr){
for(int i=0;i<arr.length-1;i++){
boolean flag=true;
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]<arr[j+1]){
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
flag=false;
}
}
if(flag){
break;
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3, 4, 5, 2, 5, 6, 7, 8};
bubbleSort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}
定义了常数个变量,空间复杂度O(1)
public static int Fun(int n){
if(n<=2)
return 1;
else
return Fun(n-1)+Fun(n-2);
}
public static void main(String[] args) {
int s=6;
System.out.println(Fun(s));
}
执行N次,就会在栈上开辟N个函数栈帧,一个函数栈帧使用常数个变量,空间复杂度O(N)