算法的時間複雜度 ---- Python數據結構與算法第1章

1. 算法的五大特性

① 輸入: 算法具有0個或多個輸入

② 輸出: 算法至少有1個或多個輸出

③ 有窮性: 算法在有限的步驟之後會自動結束而不會無限循環,並且每一個步驟可以在可接受的時間內完成

④ 確定性:算法中的每一步都有確定的含義,不會出現二義性

⑤ 可行性:算法的每一步都是可行的,也就是說每一步都能夠執行有限的次數完成

算法是獨立存在的一種解決問題的方法和思想。

2. 最壞時間複雜度

① 算法完成工作最少需要多少基本操作,即最優時間複雜度

② 算法完成工作最多需要多少基本操作,即最壞時間複雜度

③ 算法完成工作平均需要多少基本操作,即平均時間複雜度

       最優時間複雜度,其價值不大,因爲它沒有提供什麼有用信息,其反映的只是最樂觀最理想的情況,沒有參考價值;最壞時間複雜度,提供了一種保證,表明算法在此種程度的基本操作中一定能完成工作。平均時間複雜度,是對算法的一個全面評價,因此它完整全面的反映了這個算法的性質。但另一方面,這種衡量並沒有保證,不是每個計算都能在這個基本操作內完成。而且,對於平均情況的計算,也會因爲應用算法的實例分佈可能並不均勻而難以計算。

我們主要關注算法的最壞情況,亦即最壞時間複雜度。

3. 時間複雜度的基本計算規則

基本操作,即只有常數項,認爲其時間複雜度爲O(1)

順序結構,時間複雜度按加法進行計算

循環結構,時間複雜度按乘法進行計算

分支結構,時間複雜度取最大值

判斷一個算法的效率時,往往只需要關注操作數量的最高次項,其它次要項和常數項可以忽略。在沒有特殊說明時,我們所分析的算法的時間複雜度都是指最壞時間複雜度。

4. 常見時間複雜度
執行次數函數舉例 非正式術語
12 O(1) 常數階
2n+3 O(n) 線性階
3n2+2n+1 O(n2) 平方階
5log2n+20 O(logn) 對數階
2n+3nlog2n+19 O(nlogn) nlogn階
6n3+2n2+3n+4 O(n3) 立方階
2n O(2n) 指數階

經常將log2n(以2爲底的對數)簡寫成logn。

5. 常見時間複雜度之間的關係

在這裏插入圖片描述
所消耗的時間從小到大:O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n2log(n)) < O(n3) < O(2n) < O(n!) < O(nn)

6. 算法分析

如果 a+b+c=1000,且 a2+b2=c^2(a,b,c 爲自然數),如何求出所有a、b、c可能的組合?

① 第一種算法:

import time

start_time = time.time()
for a in range(1001):
    for b in range(1001):
        for c in range(1001):
            if a ** 2 + b ** 2 == c ** 2 and a + b + c == 1000:
                print("a, b, c: %d, %d, %d" % (a, b, c))
end_time = time.time()
print('%d' % (end_time - start_time))
"""
a, b, c: 0, 500, 500
a, b, c: 200, 375, 425
a, b, c: 375, 200, 425
a, b, c: 500, 0, 500
576
"""

時間複雜度:T(n) = O(nnn) = O(n3)

② 第二種算法:

import time

start_time = time.time()
for a in range(1001):
    for b in range(1001 - a):
        c = 1000 - a - b
        if a ** 2 + b ** 2 == c ** 2:
            print("a, b, c: %d, %d, %d" % (a, b, c))
end_time = time.time()
print(end_time - start_time)
"""
a, b, c: 0, 500, 500
a, b, c: 200, 375, 425
a, b, c: 375, 200, 425
a, b, c: 500, 0, 500
0.4090738296508789
"""

時間複雜度:T(n) = O(nn(1+1)) = O(n*n) = O(n2)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章