時間複雜度
遞歸求斐波那契數列時間複雜度:O(2^n)
遞歸樹分析
節點單一子問題代價:函數執行過程中,除去遞歸調用以外的代價
比如:
int fib(int n){
if(n==1 || n==2){//前2項直接返回
return 1;
}
return fib(n-1)+fib(n-2);//第3項=前兩項之和
}
1 n=1 或 n=1時,return 1 時間複雜度爲O(1)
2 n>2時 執行: fib(n-1)+fib(n-2) 除去遞歸,只有加法運算 時間複雜度爲O(1)
3 需要計算整個過程多少個O(1)
4 如果是完美二叉樹,即:所有都填滿的情況下爲O(2^n)
因此時間複雜度粗略計算爲O(2^n)
實際再(sqrt(2))^n ~2^n之間,粗略計算 O(2^n)
精確計算其時間複雜度爲:((1+sqrt(5))/2)^n
歸併排序
分析
使用歸併排序,
1 從中間把數列分成左右兩部分
2 把分成的左右2部分中每部分再分成左右2部分
3 一直分下去,直到分拆成1個數
4 再按剛纔拆的順序合併
參考程序
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],tmp[N];
void merge(int L,int R,int mid){
int i=L,j=mid+1,k=L;
while(i<=mid && j<=R){
if(a[i]<a[j]){
tmp[k++]=a[i++];
}else{
tmp[k++]=a[j++];
}
}
while(i<=mid) tmp[k++]=a[i++];
while(j<=R) tmp[k++]=a[j++];
for(int i=L;i<=R;i++){
a[i]=tmp[i];
}
}
void mergeSort(int L,int R){
if(L>=R) return;
int mid=L+(R-L)/2;
mergeSort(L,mid);//左半部分排序
mergeSort(mid+1,R);//右半部分排序
merge(L,R,mid);//合併
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
mergeSort(0,n-1);
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
return 0;
}
時間複雜度
歸併排序時間複雜度爲:O(n*logn)
節點單一子問題代價:函數執行過程中,除去遞歸調用以外的代價
歸併排序被拆分了 logn層,每層合併代價爲n,所以總代價爲n*logn