時間複雜度和空間複雜度

2021-09-22 18:01:32 字數 4535 閱讀 5141

如何衡量乙個演算法的好壞?

什麼是時間複雜度?

時間複雜度為什麼不使用時間來衡量而使用基本語句的執行次數來衡量?

時間複雜度的o漸進表示法

時間複雜度的:最優、平均、最差情況,為什麼時間複雜度看的是最差情況?

如何求解:二分查詢、遞迴求階乘、遞迴斐波那契的時間複雜度?

什麼是空間複雜度?

如何求空間複雜度? 普通函式&遞迴函式

分析遞迴斐波那契數列的:時間、空間複雜度,並對其進行優化,偽遞迴優化—>迴圈優化

總結常見時間複雜度

如何衡量乙個演算法的好壞?

演算法:就是定義良好的計算過程,他取乙個或一組的值為輸入,並產生乙個或一組作為輸出。簡單來說演算法就是一系列的計算步驟,用來輸入資料轉化為輸出結果。

演算法效率:演算法效率分析分為兩種,第一種是時間效率,第二種是空間效率。時間效率被稱為時間複雜度,主要衡量的是乙個演算法的執行速度,而空間複雜度主要衡量乙個算飯所需要的額外空間。

2.什麼是時間複雜度?

時間複雜度:什麼是時間複雜度,演算法中某個函式有n次基本操作重複執行,用t(n)表示,現在有某個輔助函式f(n),使得當n趨近於無窮大時,tn)/f(n)的極限值為不等於零的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n)),稱o(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。也就是說:演算法中基本操作的執行次數,為演算法的時間複雜度。

時間複雜度為什麼不使用時間來衡量而使用基本語句的執行次數來衡量?

乙個演算法執行所消耗的時間,從理論上是不能算出來的,只有把程式放在計算機上面跑起來,才能知道。而乙個相同的演算法在不同的機器上執行的時間可能不同,故不便於比較。而乙個演算法所執行需要的時間與它裡面執行的基本語句的次數成正比,所以用基本語句的基本次數來衡量更為合理。

時間複雜度的o漸進表示法

// 請計算一下func1基本操作執行了多少次?

void

func1

(int n)

}for

(int k =

0; k <

2* n;

++k)

int m =10;

while

(m--

)printf

("%d\n"

, count)

;}

實際中我們計算時間複雜度時,我們其實並不一定要計算精確的執行次數,而只需要大概執行次數,那麼這裡我們使用大o的漸進表示法。

大o階方法:

1、用常數1取代執行時間中的所有加法常數。

2、在修改後的執行次數函式中,只保留最高端項。

3、如果最高端項存在且不是1,則去除與這個專案相乘的常數。得到的結果就是大o階。 使用大o的漸進表示法以後,func1的時間複雜度為:

n = 10 f(n) = 100 n = 100 f(n) = 10000 n = 1000 f(n) = 1000000

通過上面我們會發現大o的漸進表示法去掉了那些對結果影響不大的項,簡潔明瞭的表示出了執行次數。

另外有些演算法的時間複雜度存在最好、平均和最壞情況:

最壞情況:任意輸入規模的最大執行次數(上界)

平均情況:任意輸入規模的期望執行次數

最好情況:任意輸入規模的最小執行次數(下界)

時間複雜度的:最優、平均、最差情況,為什麼時間複雜度看的是最差情況?

最壞情況:任意輸入規模的最大執行次數(上界)

平均情況:任意輸入規模的期望執行次數

最好情況:任意輸入規模的最小執行次數(下界)

為什麼時間複雜度要看最差情況呢?其實很容易理解,就像你去約會,為了不遲到,所以你要留出你最慢到達約會地點的時間,如果能早到當然最好不過,所以看最差情況的原因也就很明了,就是程式的正常執行的最差情況若已經滿足,這個程式在任何情況下都可以正常執行了。

如何求解:二分查詢、遞迴求階乘、遞迴斐波那契的時間複雜度?

1.//二分查詢

int

binarysearch

(int

* a,

int n,

int key)

else

if(a[mid]

> key)

else

}return-1

;}

二分查詢執行最好1次,最壞假設執行x次.

在這n個數中n/2/2直到找到key,所以就有

logn,所以該二分查詢的時間複雜度為o(logn)

.2//遞迴求階乘

long

long

factorial

(size_t n)

基本操作遞迴了n次,所以時間複雜度為o(n);

單次遞迴中執行的次數 * 遞迴函式總遞迴數;

.3.//遞迴求斐波那契

long

long

fibonacci

(size_t n)

基本操作遞迴了2^n,

所以時間複雜度為o(2^n);

什麼是空間複雜度?

空間複雜度是對乙個演算法在執行過程中臨時占用儲存空間的量度。空間複雜度不是占用了多少bytes的空間,因為這個也沒太大意義,所以空間複雜度算的是變數的個數。空間複雜度計算規則基本跟時間複雜度類似,也使用大o漸進表示法

如何求空間複雜度? 普通函式&遞迴函式

計算bubblesort的空間複雜度

void

bubblesort

(int

* a,

int n)}if

(exchange ==0)

break;}

}

計算fibonacci的空間複雜度

long

long

*fibonacci

(size_t n)

return fibarray ;

}

計算階乘遞迴factorial的時間複雜度

long

long

factorial

(size_t n)

例項1使用了常數個額外空間,所以空間複雜度為 o(1)

例項2動態開闢了n個空間,空間複雜度為 o(n)

例項3遞迴呼叫了n次,開闢了n個棧幀,每個棧幀使用了常數個空間。空間複雜度為o(n)

分析遞迴斐波那契數列的:時間、空間複雜度,並對其進行優化,偽遞迴優化—>迴圈優化

遞迴斐波那契數列

int

fib(

int n)

第n個數執行的次數為 2^ 0 + 2^ 1+…+ 2^ (n - 2)

是乙個等比數列: s = [a1 + (1 - q^ n)] / (1 - q) = 2^ (n - 2) - 2;

時間複雜度: o(2^n)

//優化

//1.迴圈優化

int

fib(

unsigned

int n)

return num;

}}

//所以時間複雜度為o(n),空間複雜度為o(1)

//2.偽遞迴優化

long

fib(

long n,

long first,

long second)

//遞迴呼叫了n 次,單次遞迴執行了常數次

//所以時間複雜度為o(n),空間複雜度為o(1)

總結常見時間複雜度

第一種

o(1)

常數複雜度, 最快的演算法

取陣列第1000000個元素

字典和集合的訪問都是o(1)

陣列的訪問是o(1)

.第二種

o(logn)

對數複雜度

假設有乙個有序陣列, 以二分法查詢

第三種o(n)

線性複雜度

假設有乙個陣列, 以遍歷的方式在其中查詢元素

.第四種

o(nlogn)

求兩個陣列的交集, 其中乙個是有序陣列

a陣列每乙個元素都要在b陣列中進行查詢操作

每次查詢如果使用二分法則複雜度是 logn

.第五種

o(n2)

平方複雜度

求兩個無序陣列的交集

演算法複雜度 時間複雜度和空間複雜度

1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...

演算法複雜度 時間複雜度和空間複雜度

演算法複雜度 時間複雜度和空間複雜度 關鍵字 演算法複雜度 時間複雜度 空間複雜度 1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時 間多,哪個演算法花費的時間少就可以...

演算法複雜度 時間複雜度和空間複雜度

演算法的時間複雜度是指執行演算法所需要的計算工作量。n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 存在乙個正...