時間復雜度:
首先要說的是,時間復雜度的計算並不是計算程序具體運行的時間,而是算法執行語句的次數。
當我們面前有多個算法時,我們可以通過計算時間復雜度,判斷出哪一個算法在具體執行時花費時間最多和最少。
常見的時間復雜度有:
常數階O(1),
對數階O(log2 n),
線性階O(n),
線性對數階O(n log2 n),
平方階O(n^2),
立方階O(n^3)
k次方階O(n^K),
指數階O(2^n)。
隨着n的不斷增大,時間復雜度不斷增大,算法花費時間越多。
計算方法
①選取相對增長最高的項
②最高項系數是都化為1
③若是常數的話用O(1)表示
如f(n)=2*n^3+2n+100則O(n)=n^3。
通常我們計算時間復雜度都是計算最壞情況
時間復雜度的計算:
(1)如果算法的執行時間不隨着問題規模n的增加而增長,即使算法中有上千條語句,其執行時間也不過是一個較大的常數。此類算法的時間復雜度是O(1)。
int x=1; while (x <10) { x++; }
- 1
- 2
- 3
- 4
- 5
該算法執行次數是10,是一個常數,用時間復雜度表示是O(1)。
(2)當有若干個循環語句時,算法的時間復雜度是由嵌套層數最多的循環語句中最內層語句的頻度f(n)決定的。
for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { ; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
該算法for循環,最外層循環每執行一次,內層循環都要執行n次,執行次數是根據n所決定的,時間復雜度是O(n^2)。
(3)循環不僅與n有關,還與執行循環所滿足的判斷條件有關。
int i=0; while (i < n && arr[i]!=1) { i++; }
- 1
- 2
- 3
- 4
- 5
在此循環,如果arr[i]不等於1的話,時間復雜度是O(n)。如果arr[i]等於1的話,則循環不能執行,時間復雜度是0。
空間復雜度
空間復雜度是對一個算法在運行過程中臨時占用存儲空間大小的量度。
計算方法:
①忽略常數,用O(1)表示
②遞歸算法的空間復雜度=遞歸深度N*每次遞歸所要的輔助空間
③對於單線程來說,遞歸有運行時堆棧,求的是遞歸最深的那一次壓棧所耗費的空間的個數,因為遞歸最深的那一次所耗費的空間足以容納它所有遞歸過程。
如:
int a; int b; int c; printf("%d %d %d \n",a,b,c);
- 1
- 2
- 3
- 4
它的空間復雜度O(n)=O(1);
int fun(int n,) { int k=10; if(n==k) return n; else return fun(++n); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
遞歸實現,調用fun函數,每次都創建1個變量k。調用n次,空間復雜度O(n*1)=O(n)。
舉例說明
1:實現二分查找算法的遞歸及非遞歸。(分析時間復雜度及空間復雜度)
迭代算法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h> #include<assert.h> int BinarySearch(int arr[], int len, int num) { assert(arr); int left = 0; int right = len - 1; int mid; while (left <= right) { mid = left + (right - left) / 2; if (num > arr[mid]) { left = mid + 1; } else if (num < arr[mid]) { right = mid - 1; } else { return mid; } } return -1; } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9 }; int length = sizeof(arr) / sizeof(arr[0]); int aim = 9; int result; result = BinarySearch(arr, length, aim); if (result == -1) { printf("Can't find %d\n", aim); } else { printf("%d at %d postion\n", aim,result + 1); } return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
二分查找時,每次都在原有查找內容進行二分,所以時間復雜度為O(log2 n)
因為變量值創建一次,所以空間復雜度為O(1)
遞歸算法
int BinarySearchRecursion(int arr[5], int lef, int rig,int aim) { int mid = lef + (rig - lef) / 2; if (lef <= rig) { if (aim < arr[mid]) { rig = mid - 1; BinarySearchRecursion(arr, lef, rig, aim); } else if (arr[mid] < aim) { lef = mid + 1; BinarySearchRecursion(arr, lef, rig, aim); } else if (aim == arr[mid]) { return mid; } } else return -1; } int main() { int arr[] = { 1,2,3,5,6, }; int sz = sizeof(arr)/sizeof(arr[0]); int result; result = BinarySearchRecursion(arr, 0, sz - 1, 4); if (-1 == result) { printf("Can't find it.\n"); } else printf("Aim at %d location\n", result+1); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
時間復雜度為O(log2 n)
每進行一次遞歸都會創建變量,所以空間復雜度為O(log2 n)
2:實現斐波那契數列的遞歸及非遞歸。(分析時間復雜度及空間復雜度)
迭代算法
int FeiBoNaCciInteration(int a,int b,int num) { int c; if (num <= 0) return -1; else if (num == 1) return a; else if (num == 2) return b; else { while (num - 2) { c = a + b; a = b; b = c; num--; } return c; } } int main() { int n; int result; printf("Input n\n"); scanf("%d", &n); result = FeiBoNaCciInteration(2, 3, n);//可自定義輸入第一個數和第二個數 if (result == -1) { printf("Input Error!\n"); } else { printf("n is %d\n", result); } return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
時間復雜度O(n)
空間復雜度為O(1)
遞歸算法
int FeiBoNaCciRecursion(int num) { if (num < 0) return -1; if (num <= 2 && num > 0) return 1; else return FeiBoNaCciRecursion(num - 1) + FeiBoNaCciRecursion(num - 2); } int main() { int n; int result; printf("Input n\n"); scanf("%d", &n); result = FeiBoNaCciRecursion(n); if (result == -1) printf("Input Error!\n"); else printf("Result is %d\n", result); return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
時間復雜度為O(2^n)
空間復雜度為O(n)
