遞歸時間複雜度

時間複雜度

遞歸求斐波那契數列時間複雜度: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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章