(1) for(i=1;i<=n;i++) //循環了n*n次,當然是O(n^2) for(j=1;j<=n;j++) s++; (2) for(i=1;i<=n;i++)//循環了(n+n-1+n-2+...+1)≈(n^2)/2,因為時間復雜度是不考慮系數的,所以也是O(n^2) for(j=i;j<=n;j++) s++; (3) for(i=1;i<=n;i++)//循環了(1+2+3+...+n)≈(n^2)/2,當然也是O(n^2) for(j=1;j<=i;j++) s++; (4) i=1;k=0;
while(i<=n-1){
k+=10*i;
i++; }
//循環了
n-1≈n次,所以是O(n)
(5) for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
for(k=1;k<=j;k++)
x=x+1;
//
循環了(1^2+2^2+3^2+...+n^2)=n(n+1)(2n+1)/6(這個公式要記住哦)≈(n^3)/3,不考慮系數,自然是O(n^3)
另外,在時間復雜度中,log(2,n)(以2為底)與lg(n)(以10為底)是等價的,因為對數換底公式:
定義:如果一個問題的規模是n,解這一問題的某一算法所需要的時間為T(n),它是n的某一函數 T(n)稱為這一算法的“時間復雜性”。
當輸入量n逐漸加大時,時間復雜性的極限情形稱為算法的“漸近時間復雜性”。 我們常用大O表示法表示時間復雜性,注意它是某一個算法的時間復雜性。大O表示只是說有上界,由定義如果f(n)=O(n),那顯然成立f(n)=O(n^2),它給你一個上界,但並不是上確界,但人們在表示的時候一般都習慣表示前者。 此外,一個問題本身也有它的復雜性,如果某個算法的復雜性到達了這個問題復雜性的下界,那就稱這樣的算法是最佳算法。 “大O記法”:在這種描述中使用的基本參數是 n,即問題實例的規模,把復雜性或運行時間表達為n的函數。這里的“O”表示量級 (order),比如說“二分檢索是 O(logn)的”,也就是說它需要“通過logn量級的步驟去檢索一個規模為n的數組”記法 O ( f(n) )表示當 n增大時,運行時間至多將以正比於 f(n)的速度增長。 這種漸進估計對算法的理論分析和大致比較是非常有價值的,但在實踐中細節也可能造成差異。例如,一個低附加代價的O(n2)算法在n較小的情況下可能比一個高附加代價的 O(nlogn)算法運行得更快。當然,隨着n足夠大以后,具有較慢上升函數的算法必然工作得更快。 O(1) Temp=i;i=j;j=temp; 以上三條單個語句的頻度均為1,該程序段的執行時間是一個與問題規模n無關的常數。算法的時間復雜度為常數階,記作T(n)=O(1)。如果算法的執行時間不隨着問題規模n的增加而增長,即使算法中有上千條語句,其執行時間也不過是一個較大的常數。此類算法的時間復雜度是O(1)。 O(n^2) 2.1. 交換i和j的內容 sum=0; (一次) for(i=1;i<=n;i++) (n次 ) for(j=1;j<=n;j++) (n^2次 ) sum++; (n^2次 ) 解:T(n)=2n^2+n+1 =O(n^2) 2.2. for (i=1;i<n;i++) { y=y+1; ① for (j=0;j<=(2*n);j++) x++; ② } 解: 語句1的頻度是n-1 語句2的頻度是(n-1)*(2n+1)=2n^2-n-1 f(n)=2n^2-n-1+(n-1)=2n^2-2 該程序的時間復雜度T(n)=O(n^2). O(n) 2.3. a=0; b=1; ① for (i=1;i<=n;i++) ② { s=a+b; ③ b=a; ④ a=s; ⑤ } 解:語句1的頻度:2, 語句2的頻度: n, 語句3的頻度: n-1, 語句4的頻度:n-1, 語句5的頻度:n-1, T(n)=2+n+3(n-1)=4n-1=O(n). O(log2n ) 2.4. i=1; ① while (i<=n) i=i*2; ② 解: 語句1的頻度是1, 設語句2的頻度是f(n), 則:2^f(n)<=n;f(n)<=log2n 取最大值f(n)= log2n, T(n)=O(log2n ) O(n^3) 2.5. for(i=0;i<n;i++) { for(j=0;j<i;j++) { for(k=0;k<j;k++) x=x+2; } } 解:當i=m, j=k的時候,內層循環的次數為k當i=m時, j 可以取 0,1,...,m-1 , 所以這里最內循環共進行了0+1+...+m-1=(m-1)m/2次所以,i從0取到n, 則循環共進行了: 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以時間復雜度為O(n^3). 我們還應該區分算法的最壞情況的行為和期望行為。如快速排序的最 壞情況運行時間是 O(n^2),但期望時間是 O(nlogn)。通過每次都仔細 地選擇基准值,我們有可能把平方情況 (即O(n^2)情況)的概率減小到幾乎等於 0。在實際中,精心實現的快速排序一般都能以 (O(nlogn)時間運行。 下面是一些常用的記法: 訪問數組中的元素是常數時間操作,或說O(1)操作。一個算法如 果能在每個步驟去掉一半數據元素,如二分檢索,通常它就取 O(logn)時間。用strcmp比較兩個具有n個字符的串需要O(n)時間。常規的矩陣乘算法是O(n^3),因為算出每個元素都需要將n對 元素相乘並加到一起,所有元素的個數是n^2。 指數時間算法通常來源於需要求出所有可能結果。例如,n個元 素的集合共有2n個子集,所以要求出所有子集的算法將是O(2n)的。指數算法一般說來是太復雜了,除非n的值非常小,因為,在 這個問題中增加一個元素就導致運行時間加倍。不幸的是,確實有許多問題 (如著名的“巡回售貨員問題” ),到目前為止找到的算法都是指數的。如果我們真的遇到這種情況,通常應該用尋找近似最佳結果的算法替代之。
https://blog.csdn.net/firefly_2002/article/details/8008987
https://blog.csdn.net/qq_15237565/article/details/77885311
數據結構中的時間復雜度的計算算法的時間復雜度定義為: 時間復雜度或稱時間復雜性,又稱計算復雜度,她說是算法有效的度量之一,時間復雜度是一個算法運行時間的相對度量,一個算法的運行時間長短,它大致等於執行一種簡單操作所(賦值、比較、計算、轉向、返回、輸入和輸出)需要的時間與算法中進行簡單操作次數的乘積。 根據定義,求解算法的時間復雜度的具體步驟是: ⑴ 找出算法中的基本語句; ⑵ 計算基本語句的執行次數的數量級; ⑶ 用大Ο記號表示算法的時間性能。 簡單的說,就是保留求出次數的最高次冪,並且把系數去掉。 如T(n)=2n^2+n+1=O(n^2) 舉個例子:
照上面推導“大O階”的步驟,我們來看 第一步:“用常數 1 取代運行時間中的所有加法常數”, 則上面的算式變為:執行總次數 =3n^2 + 3n + 1 (直接相加的話,應該是T(n) = 1 + n+1 + n +n*(n+1) + n*n + n*n + 1 = 3n^2 + 3n + 3。現在用常數 1 取代運行時間中的所有加法常數,就是把T(n) =3n^2 + 3n + 3中的最后一個3改為1. 就得到了 T(n) = 3n^2 + 3n + 1) 第二步:“在修改后的運行次數函數中,只保留最高階項”。 這里的最高階是 n 的二次方,所以算式變為:執行總次數 = 3n^2 第三步:“如果最高階項存在且不是 1 ,則去除與這個項相乘的常數”。 這里 n 的二次方不是 1 所以要去除這個項的相乘常數,算式變為:執行總次數 = n^2 下面我把常見的算法時間復雜度以及他們在效率上的高低順序記錄在這里,使大家對算法的效率有個直觀的認識。 O(1) 常數階 < O(logn) 對數階 < O(n) 線性階 < O(nlogn) < O(n^2) 平方階 < O(n^3) < { O(2^n) < O(n!) <O(n^n) } 最后三項用大括號把他們括起來是想要告訴大家,如果日后大家設計的算法推導出的“大O階”是大括號中的這幾位,那么趁早放棄這個算法,在去研究新的算法出來吧。因為大括號中的這幾位即便是在 n 的規模比較小的情況下仍然要耗費大量的時間,算法的時間復雜度大的離譜,基本上就是“不可用狀態。
好了,原理就介紹到這里了。下面通過幾個例子具體分析下時間復雜度計算過程。
一、計算
1 + 2 + 3 + 4 + ...... + 100。
常規代碼:
從代碼附加的注釋可以看到所有代碼都執行了多少次。那么這寫代碼語句執行次數的總和就可以理解為是該算法計算出結果所需要的時間。該算法所用的時間(算法語句執行的總次數)為:
1 + ( n + 1 ) + n + 1 = 2n + 3
而當 n 不斷增大,比如我們這次所要計算的不是 1 + 2 + 3 + 4 +...... + 100 = ? 而是 1 + 2 + 3 + 4 + ...... + n = ?其中 n 是一個十分大的數字,那么由此可見,上述算法的執行總次數(所需時間)會隨着 n 的增大而增加,但是在 for 循環以外的語句並不受 n 的規模影響(永遠都只執行一次)。所以我們可以將上述算法的執行總次數簡單的記做: 2n 或者簡記 n 這樣我們就得到了我們設計的算法的時間復雜度,我們把它記作: O(n)。
高斯算法:
這個算法的時間復雜度: O(3),但一般記作 O(1)。
二、求兩個
n 階方陣 C=A*B 的乘積其算法如下 :
則該算法所有語句的頻度之和為:
三、分析下列時間復雜度
設for循環語句執行次數為T(n),則 i = 2T(n) + 1 <= n - 1, 即T(n) <= n/2 - 1 = O(n) 四、分析下列時間復雜度
其中,算法的基本運算語句是 if (b[k] > b[j]) { k = j; } 其執行次數T(n)為:
五、分析下列時間復雜度
其中,算法的基本運算語句即while循環內部分, 設 while 循環語句執行次數為 T(n), 則
六、Hanoi(遞歸算法)時間復雜度分析
對於遞歸函數的分析,跟設計遞歸函數一樣,要先考慮基情況(比如hanoi中n==1時候),這樣把一個大問題划分為多個子問題的求解。
故此上述算法的時間復雜度的遞歸關系如下
:
![]() |