日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

复杂度分析学习总结

發(fā)布時(shí)間:2025/3/21 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复杂度分析学习总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

復(fù)雜度分析學(xué)習(xí)總結(jié)

1、大 O 復(fù)雜度表示法

T(n) = O( f(n) )

其中,T(n) 表示代碼執(zhí)行的時(shí)間;n 表示數(shù)據(jù)規(guī)模的大小;f(n) 表示每行代碼執(zhí)行的次數(shù)總和。公式中的 O,表示代碼的執(zhí)行時(shí)間 T(n) 與 f(n) 表達(dá)式成正比。

大 O 時(shí)間復(fù)雜度實(shí)際上并不具體表示代碼真正的執(zhí)行時(shí)間,而是表示代碼執(zhí)行時(shí)間隨數(shù)據(jù)規(guī)模增長(zhǎng)的變化趨勢(shì),所以,也叫作漸進(jìn)時(shí)間復(fù)雜度(asymptotic time complexity),簡(jiǎn)稱時(shí)間復(fù)雜度

int cal1(int n) {int sum = 0;int i = 1;for (; i <= n; ++i) {sum = sum + i;}return sum;}int cal2(int n) {int sum = 0;int i = 1;int j = 1;for (; i <= n; ++i) {j = 1;for (; j <= n; ++j) {sum = sum + i * j;}}}

上面例子中,第一個(gè)的 T(n) = O(2n+2),第二個(gè)的 T(n) = O(2n2+2n+3),當(dāng) n 很大時(shí),可以把它想象成 10000、100000。而公式中的低階、常量、系數(shù)三部分并不左右增長(zhǎng)趨勢(shì),所以都可以忽略。只需要記錄一個(gè)最大量級(jí)就可以了,如果用大 O 表示法表示剛講的那兩段代碼的時(shí)間復(fù)雜度,就可以記為:T(n) = O(n); T(n) = O(n^2)。

2、時(shí)間復(fù)雜度分析方法

(1) 只關(guān)注循環(huán)執(zhí)行次數(shù)最多的一段代碼

(2) 加法法則:總復(fù)雜度等于量級(jí)最大的那段代碼的復(fù)雜度

這個(gè)規(guī)律抽象成公式就是:

如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)+T2(n)=max(O(f(n)), O(g(n))) =O(max(f(n), g(n)))

(3)乘法法則:嵌套代碼的復(fù)雜度等于嵌套內(nèi)外代碼復(fù)雜度的乘積

這個(gè)規(guī)律抽象成公式就是:

如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))

舉個(gè)例子:

int cal(int n) {int ret = 0; int i = 1;for (; i < n; ++i) {ret = ret + f(i);} } int f(int n) {int sum = 0;int i = 1;for (; i < n; ++i) {sum = sum + i;} return sum;}

如果單獨(dú)看 cal() 函數(shù),假設(shè) f() 只是一個(gè)普通的操作,那第 4~6 行的時(shí)間復(fù)雜度就是,T1(n) = O(n)。但 f() 函數(shù)本身不是一個(gè)簡(jiǎn)單的操作,它的時(shí)間復(fù)雜度是 T2(n) = O(n),所以,整個(gè) cal() 函數(shù)的時(shí)間復(fù)雜度就是,T(n) = T1(n) * T2(n) = O(n*n) =O(n^2)。

?

3、幾種常見(jiàn)時(shí)間復(fù)雜度實(shí)例分析

可以粗略的分為:多項(xiàng)式量級(jí)和非多項(xiàng)式量級(jí)

(1)非多項(xiàng)式量級(jí)

非多項(xiàng)式量級(jí)只有兩個(gè):O(2n) 和 O(n!)。

我們把時(shí)間復(fù)雜度為非多項(xiàng)式量級(jí)的算法問(wèn)題叫作 NP(Non-Deterministic Polynomial,非確定多項(xiàng)式)問(wèn)題。當(dāng)數(shù)據(jù)規(guī)模 n 越來(lái)越大時(shí),非多項(xiàng)式量級(jí)算法的執(zhí)行時(shí)間會(huì)急劇增加,求解問(wèn)題的執(zhí)行時(shí)間會(huì)無(wú)限增長(zhǎng)。所以,非多項(xiàng)式時(shí)間復(fù)雜度的算法其實(shí)是非常低效的算法。

(2)多項(xiàng)式量級(jí)

一般常見(jiàn)的,從低階到高階有:O(1)、O(logn)、O(n)、O(nlogn)、O(n^2)

時(shí)間復(fù)雜度趨勢(shì)圖如下:

其中O(logn)、O(nlogn)比較特殊,如下例子可以說(shuō)明

i=1;while (i <= n) {i = i * 2;} // 這段代碼的時(shí)間復(fù)雜度就是 O(log2 n)i=1; while (i <= n) { i = i * 3; } // 這段代碼的時(shí)間復(fù)雜度就是 O(log3 n)

在對(duì)數(shù)階時(shí)間復(fù)雜度的表示方法里,可以忽略對(duì)數(shù)的“底”,統(tǒng)一表示為 O(logn)

有種情況是,如果我們無(wú)法事先評(píng)估 m 和 n 誰(shuí)的量級(jí)大,所以我們?cè)诒硎緩?fù)雜度的時(shí)候,就不能簡(jiǎn)單地利用加法法則,省略掉其中一個(gè),如下例子的時(shí)間復(fù)雜度是:O(m+n)、O(m*n)

int cal(int m, int n) {int sum_1 = 0;int i = 1;for (; i < m; ++i) {sum_1 = sum_1 + i;}int sum_2 = 0;int j = 1;for (; j < n; ++j) {sum_2 = sum_2 + j;}return sum_1 + sum_2; }

?

4、空間復(fù)雜度分析

定義:時(shí)間復(fù)雜度的全稱是漸進(jìn)時(shí)間復(fù)雜度,表示算法的執(zhí)行時(shí)間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系。類比一下,空間復(fù)雜度全稱就是漸進(jìn)空間復(fù)雜度(asymptotic space complexity),表示算法的存儲(chǔ)空間與數(shù)據(jù)規(guī)模之間的增長(zhǎng)關(guān)系

空間復(fù)雜度的定義的比較簡(jiǎn)單,例子如下

void print(int n) {int i = 0;int[] a = new int[n];for (i; i <n; ++i) {a[i] = i * i;}for (i = n-1; i >= 0; --i) {print out a[i]} }

跟時(shí)間復(fù)雜度分析一樣,可以看到,第 2 行代碼中,我們申請(qǐng)了一個(gè)空間存儲(chǔ)變量 i,但是它是常量階的,跟數(shù)據(jù)規(guī)模 n 沒(méi)有關(guān)系,所以我們可以忽略。第 3 行申請(qǐng)了一個(gè)大小為 n 的 int 類型數(shù)組,除此之外,剩下的代碼都沒(méi)有占用更多的空間,所以整段代碼的空間復(fù)雜度就是 O(n)。

?

5、四個(gè)復(fù)雜度分析方面知識(shí)點(diǎn)

最好情況時(shí)間復(fù)雜度(best case time complexity)、最壞情況時(shí)間復(fù)雜度(worst case time complexity)、平均情況時(shí)間復(fù)雜度(average case time complexity)、均攤時(shí)間復(fù)雜度(amortized time complexity)

(1)最好情況時(shí)間復(fù)雜度、最壞情況時(shí)間復(fù)雜度

顧名思義,最好情況時(shí)間復(fù)雜度就是,在最理想的情況下,執(zhí)行這段代碼的時(shí)間復(fù)雜度,最壞情況時(shí)間復(fù)雜度就是,在最糟糕的情況下,執(zhí)行這段代碼的時(shí)間復(fù)雜度

(2)平均情況時(shí)間復(fù)雜度、均攤時(shí)間復(fù)雜度

平均時(shí)間復(fù)雜度的全稱又叫加權(quán)平均時(shí)間復(fù)雜度或者期望時(shí)間復(fù)雜度

// n表示數(shù)組array的長(zhǎng)度 int find(int[] array, int n, int x) {int i = 0;int pos = -1;for (; i < n; ++i) {if (array[i] == x) {pos = i;break;}}return pos; }

要查找的變量 x 在數(shù)組中的位置,有 n+1 種情況:在數(shù)組的 0~n-1 位置中和不在數(shù)組中。把每種情況下,查找需要遍歷的元素個(gè)數(shù)累加起來(lái),然后再除以 n+1,就可以得到需要遍歷的元素個(gè)數(shù)的平均值,即:

時(shí)間復(fù)雜度的大 O 標(biāo)記法中,可以省略掉系數(shù)、低階、常量,所以,咱們把剛剛這個(gè)公式簡(jiǎn)化之后,得到的平均時(shí)間復(fù)雜度就是 O(n)。這個(gè)結(jié)論雖然是正確的,但是計(jì)算過(guò)程稍微有點(diǎn)兒?jiǎn)栴}。這 n+1 種情況,出現(xiàn)的概率并不是一樣的。要查找的變量 x,要么在數(shù)組里,要么就不在數(shù)組里。假設(shè)在數(shù)組中與不在數(shù)組中的概率都為 1/2。另外,要查找的數(shù)據(jù)出現(xiàn)在 0~n-1 這 n 個(gè)位置的概率也是一樣的,為 1/n。所以,根據(jù)概率乘法法則,要查找的數(shù)據(jù)出現(xiàn)在 0~n-1 中任意位置的概率就是 1/(2n)。因此,如果平均時(shí)間復(fù)雜度為O(n)的最大問(wèn)題就是,沒(méi)有將各種情況發(fā)生的概率考慮進(jìn)去。

如果把每種情況發(fā)生的概率也考慮進(jìn)去,那平均時(shí)間復(fù)雜度的計(jì)算過(guò)程就變成了這樣:

這個(gè)值就是概率論中的加權(quán)平均值,也叫作期望值,所以平均時(shí)間復(fù)雜度的全稱應(yīng)該叫加權(quán)平均時(shí)間復(fù)雜度或者期望時(shí)間復(fù)雜度。引入概率之后,前面那段代碼的加權(quán)平均值為 (3n+1)/4。用大 O 表示法來(lái)表示,去掉系數(shù)和常量,這段代碼的加權(quán)平均時(shí)間復(fù)雜度仍然是 O(n)。

?

均攤時(shí)間復(fù)雜度

// array表示一個(gè)長(zhǎng)度為n的數(shù)組// 代碼中的array.length就等于nint[] array = new int[n];int count = 0;void insert(int val) {if (count == array.length) {int sum = 0;for (int i = 0; i < array.length; ++i) {sum = sum + array[i];}array[0] = sum;count = 1;}array[count] = val;++count;}

在數(shù)組中插入數(shù)據(jù)的這個(gè)例子。每一次 O(n) 的插入操作,都會(huì)跟著 n-1 次 O(1) 的插入操作,所以把耗時(shí)多的那次操作均攤到接下來(lái)的 n-1 次耗時(shí)少的操作上,均攤下來(lái),這一組連續(xù)的操作的均攤時(shí)間復(fù)雜度就是 O(1)

均攤時(shí)間復(fù)雜度就是一種特殊的平均時(shí)間復(fù)雜度,均攤時(shí)間復(fù)雜度和攤還分析應(yīng)用場(chǎng)景比較特殊,所以并不會(huì)經(jīng)常用到,在能夠應(yīng)用均攤時(shí)間復(fù)雜度分析的場(chǎng)合,一般均攤時(shí)間復(fù)雜度就等于最好情況時(shí)間復(fù)雜度。

?

總結(jié)

以上是生活随笔為你收集整理的复杂度分析学习总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。