算法是指用来操作数据、解决程序问题的一组方法。
衡量不同的算法之间的优劣要从算法所占用的时间和空间两个维度去考量。
- 时间维度:执行当前算法所消耗的时间(时间复杂度)
- 空间维度:执行当前算法需要占用的内存空间(空间复杂度)
程序员提出通用的方法进行算法的时间复杂度分析:T(n)=O(f(n))
n:表示数据规模
O(f(n)):表示运行算法所需要执行的指令数,和f(n)成正比。
常见的时间复杂度量级进行大O的理解:
大O不是代码执行的实际时间,而是执行时间的最大量级。分析一段代码的时间复杂度的时候只关注循环执行次数最多的那段代码。
- 常数阶O(1)
无论代码执行多少行,其他区域不会影响到操作。算法中不存在循环语句、递归语句。
void swap(int &a,int &b){
int temp=a;
a=b;
b=temp;
}
- 线性阶O(n)
下面for循环里面的代码会执行n遍,消耗的时间随着n的变化而变化,因此可以用O(n)表示时间复杂度
int sum(int n){
int ret=0;
for(int i=0;i<=n;i++){
ret+=i;
}
return ret;
}
- 平方阶O(n2)
当存在双重循环时,即把O(n)的代码再嵌套循环一遍,它的时间复杂度就为O(n2)
void selsctionSort(int arr[],int n){
for(int i=0;i<n;i++){
int minIndex=i;
for(int j=i+1;j<n;j++){
if(arr[j]<arr[minIndex]){
minIndex=j;
}
swap(arr[i],arr[minIndex]);
}
}
}
- 对数阶O(logn)
每次循环乘以2,当大于n时,循环结束。
设循环次数为x,则2x>n停止。复杂度为O(log₂n).
int i;
while(i<=n){
i=i*2;
}
二分查找法的代码中,通过while循环,成二倍数的缩减范围,需要经过 log2^n次可跳出循环。
int binarySearch(int arr[],int n,int target){
int l=0,r=n-1;
while(l<=r){
int mid=l+(r-l)/2;
if(arr[mid]==target) return mid;
if(arr[mid]>target) r=mid-1;
else l=mid+1;
}
return -1;
}
- 线性对数阶O(nlogn)
时间复杂度为O(logn)的代码循环N遍,那么它的时间复杂度就是O(nlogn);
归并排序、快速排序的时间复杂度都是O(nlogn)