時間復雜度和空間復雜度的簡單講解


時間復雜度和空間復雜度的簡單講解

一個算法的優劣主要從算法的執行時間和所需要占用的存儲空間兩個方面衡量

文章最后,舉例使用二分查找和斐波那契的遞歸和迭代方法,分別說明時間和空間復雜度。

時間復雜度:
首先要說的是,時間復雜度的計算並不是計算程序具體運行的時間,而是算法執行語句的次數。
當我們面前有多個算法時,我們可以通過計算時間復雜度,判斷出哪一個算法在具體執行時花費時間最多和最少。

常見的時間復雜度有:
常數階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)。

 

1     int x=1;
2     while (x <10)
3     {
4         x++;
5     }

 

該算法執行次數是10,是一個常數,用時間復雜度表示是O(1)。

(2)當有若干個循環語句時,算法的時間復雜度是由嵌套層數最多的循環語句中最內層語句的頻度f(n)決定的。

1  for (i = 0; i < n; i++)
2     {
3         for (j = 0; j < n; j++)
4         {
5             ;
6         }
7     }

該算法for循環,最外層循環每執行一次,內層循環都要執行n次,執行次數是根據n所決定的,時間復雜度是O(n^2)。

(3)循環不僅與n有關,還與執行循環所滿足的判斷條件有關。

1 int i=0;
2 while (i < n && arr[i]!=1)
3     {
4         i++;
5     }

在此循環,如果arr[i]不等於1的話,時間復雜度是O(n)。如果arr[i]等於1的話,則循環不能執行,時間復雜度是0。

空間復雜度
空間復雜度是對一個算法在運行過程中臨時占用存儲空間大小的量度。
計算方法:
①忽略常數,用O(1)表示
②遞歸算法的空間復雜度=遞歸深度N*每次遞歸所要的輔助空間
③對於單線程來說,遞歸有運行時堆棧,求的是遞歸最深的那一次壓棧所耗費的空間的個數,因為遞歸最深的那一次所耗費的空間足以容納它所有遞歸過程。

如:

1 int a;
2 int b;
3 int c;
4 printf("%d %d %d \n",a,b,c);

它的空間復雜度O(n)=O(1);

1 int fun(int n,)
2 {
3 int k=10;
4 if(n==k)
5 return n;
6 else
7 return fun(++n);
8 }

遞歸實現,調用fun函數,每次都創建1個變量k。調用n次,空間復雜度O(n*1)=O(n)。

舉例說明

1:實現二分查找算法的遞歸及非遞歸。(分析時間復雜度及空間復雜度)

迭代算法

 1 #define _CRT_SECURE_NO_WARNINGS
 2 
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<assert.h>
 6 
 7 int BinarySearch(int arr[], int len, int num)
 8 {
 9     assert(arr);
10 
11     int left = 0;
12     int right = len - 1;
13     int mid;
14 
15     while (left <= right)
16     {
17         mid = left + (right - left) / 2;
18 
19         if (num > arr[mid])
20         {
21             left = mid + 1;
22         }
23         else if (num < arr[mid])
24         {
25             right = mid - 1;
26         }
27         else
28         {
29             return mid;
30         }
31     }
32 
33     return -1;
34 }
35 
36 
37 
38 int main()
39 {
40     int arr[] = { 1,2,3,4,5,6,7,8,9 };
41     int length = sizeof(arr) / sizeof(arr[0]);
42     int aim = 9;
43     int result;
44 
45     result = BinarySearch(arr, length, aim);
46 
47     if (result == -1)
48     {
49         printf("Can't find %d\n", aim);
50     }
51     else
52     {
53         printf("%d at %d postion\n", aim,result + 1);
54     }
55 
56 
57     return 0;
58 }

二分查找時,每次都在原有查找內容進行二分,所以時間復雜度為O(log2 n)
因為變量值創建一次,所以空間復雜度為O(1)

遞歸算法

 1 int BinarySearchRecursion(int arr[5], int lef, int rig,int aim)
 2 {
 3     int mid = lef + (rig - lef) / 2;
 4 
 5 
 6     if (lef <= rig)
 7     {
 8         if (aim < arr[mid])
 9         {
10             rig = mid - 1;
11             BinarySearchRecursion(arr, lef, rig, aim);
12         }
13         else if (arr[mid] < aim)
14         {
15             lef = mid + 1;
16             BinarySearchRecursion(arr, lef, rig, aim);
17         } 
18         else if (aim == arr[mid])
19         {
20             return mid;
21         }
22 
23     }
24     else
25         return -1;
26 
27 }
28 
29 
30 int main()
31 {
32     int arr[] = { 1,2,3,5,6, };
33     int sz = sizeof(arr)/sizeof(arr[0]);
34     int result;
35 
36     result = BinarySearchRecursion(arr, 0, sz - 1, 4);
37 
38     if (-1 == result)
39     {
40         printf("Can't find it.\n");
41     }
42     else
43         printf("Aim at %d location\n", result+1);
44 }

時間復雜度為O(log2 n)
每進行一次遞歸都會創建變量,所以空間復雜度為O(log2 n)

2:實現斐波那契數列的遞歸及非遞歸。(分析時間復雜度及空間復雜度)

迭代算法

 1 int FeiBoNaCciInteration(int a,int b,int num)
 2 {
 3     int c;
 4 
 5     if (num <= 0)
 6         return -1;
 7     else if (num == 1)
 8         return a;
 9     else if (num == 2)
10         return b;
11     else
12     {
13         while (num - 2)
14         {
15             c = a + b;
16             a = b;
17             b = c;
18             num--;
19         }
20         return c;
21     }
22 
23 }
24 
25 int main()
26 {
27     int n;
28     int result;
29 
30     printf("Input n\n");
31     scanf("%d", &n);
32 
33     result = FeiBoNaCciInteration(2, 3, n);//可自定義輸入第一個數和第二個數
34     if (result == -1)
35     {
36         printf("Input Error!\n");
37     }
38     else
39     {
40         printf("n is %d\n", result);
41     }
42 
43     return 0;
44 }

時間復雜度O(n)
空間復雜度為O(1)

遞歸算法

 1 int FeiBoNaCciRecursion(int num)
 2 {
 3     if (num < 0)
 4         return -1;
 5     if (num <= 2 && num > 0)
 6         return 1;
 7     else
 8         return FeiBoNaCciRecursion(num - 1) + FeiBoNaCciRecursion(num - 2);
 9 
10 }
11 
12 int main()
13 {
14     int n;
15     int result;
16 
17     printf("Input n\n");
18     scanf("%d", &n);
19 
20     result = FeiBoNaCciRecursion(n);
21 
22     if (result == -1)
23         printf("Input Error!\n");
24     else
25         printf("Result is %d\n", result);
26 
27     return 0;
28 }

時間復雜度為O(2^n)
空間復雜度為O(n)

--------------------- 作者:HaloTrriger 來源:CSDN 原文:https://blog.csdn.net/halotrriger/article/details/78994122?utm_source=copy 版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM