演算法時間複雜度
(The Complexity of Algorith
ms)
演算法效率分析
影響程式執行時間的因素,最簡單的有 機器的速度 演算法的好壞 演算法 (algorithm) 是一解決問題的有限步 驟之程序。 演算法的好壞,必須做複雜度的分析 (compl exity analysis) 。 分析演算法的複雜度,必須先求出程式中每 一敘述的執行次數,並加總起來,然後求出 其 Big-O 。執行時間 = 執行次數 * 每次執行所需 的時間。 由於每一敘述所需的時間必須考慮到機器 和編譯器的功能,因此通常只考慮執行的 次數而已。
例如:
x=x+1; for (i=1; i <= n; i++) for(i=1; i<=n; i++) x=x+1; for(j=1; j<=n; j++) x=x+1;
1 次 n 次 n2次
陣列
int sum(int arr[ ], int n)
{
int i, total=0;
for (i=0; i < n; i++)
total += arr[i];
return total;
}
執行次數
1
n+1
n
1
________
2n+3
矩陣相加
假設兩矩陣 a, b 皆為 n*n 。
void add(int a[ ][ ], int b[ ][ ], int c[ ][ ], int n) {
int i, j;
for(i=0; i<n; i++)
for (j=0; j<n; j++) c[i][j] =a[i][j]+b[i][j]; } 執行次數 1 n+1 n(n+1) n2 ________ 2n2+2n+2
矩陣相乘
void mul(int a[ ][ ], int b[ ][ ], int c[ ][ ], int n) {
int i, j, k, sum;
for (i=0; i < n; i++) for (j=0; j < n; j++) { sum = 0; for (k=0; k < n; k++) sum = sum+a[i][k]*b[k][j]; c[i][j] = sum; } } 執行次數 1 n+1 n(n+1) n2 n2(n+1) n3 n2 ___________ 2n3+4n2+2n+2
Big-O
算完程式敘述的執行次數後,通常利
用
Big-O 來表示此演算法的執行時間
,表示如
O(n) ,亦稱為該程式的
「時間複雜度
(time complexity) 」。
Big-O 取執行次數中最高次方或最大
指數部份的項目即可。 如:
陣列元素相加為 2n+3 = O(n)
矩陣相加為 2n
2+2n+1 = O(n
2)
矩陣相乘為 2n
3+4n
2+2n+2 = O(n
3)
運用時間複雜度的觀念,我們可以判
1. O(1) :常數時間 (constant time)
2. O(log n) :次線性時間 (sub-linea
r)
3. O(n) :線性時間 (linear)
4. O(n log n)
5. O(n
2) :平方時間 (quadratic)
6. O(n
3) :立方時間 (cubic)
7. O(2
n) :指數時間 (exponential)
8. O(n!) :階乘時間 (factorial)
如果
n
很大時
→
1< log n < n < n log n < n
2< n
3< 2
n< n!
複雜度等級
Example
1. 若ㄧ個程式執行時間是 1000n^2
+nlogn, 求其 big-O
複雜度分析
以循序搜尋為例:
int search (int data[ ], int target, int n) {
int i;
for (i=0; i < n; i++)
if ( target == data[i]) return[i]; } 最佳次數:當資料在第一筆時,第一次就找 到。 最差次數:當資料不存在或資料在最後一筆 時,需要 N 次。 平均次數: 1 ) 1 ( 1 1
n n n n二元搜尋— O(?)
binsrch(int A[], int n, int x, int j) {
lower = 1; upper = n;
while (lower <= upper) {
mid = (lower + upper) / 2; if (x > A[mid]) lower = mid + 1; else if (x < A[mid]) upper = mid – 1; else { j = mid; return; } } }